BFC的深刻理解

常見定位方案

在講 BFC 以前,咱們先來了解一下常見的定位方案,定位方案是控制元素的佈局,有三種常見方案:css

  • 普通流 (normal flow)

    在普通流中,元素按照其在 HTML 中的前後位置至上而下佈局,在這個過程當中,行內元素水平排列,直到當行被佔滿而後換行,塊級元素則會被渲染爲完整的一個新行,除非另外指定,不然全部元素默認都是普通流定位,也能夠說,普通流中元素的位置由該元素在 HTML 文檔中的位置決定。html

  • 浮動 (float)

    在浮動佈局中,元素首先按照普通流的位置出現,而後根據浮動的方向儘量的向左邊或右邊偏移,其效果與印刷排版中的文本環繞類似。佈局

  • 絕對定位 (absolute positioning)

    在絕對定位佈局中,元素會總體脫離普通流,所以絕對定位元素不會對其兄弟元素形成影響,而元素具體的位置由絕對定位的座標決定。post

BFC的定義

Formatting context(格式化上下文) 是 W3C CSS2.1 規範中的一個概念。它是頁面中的一塊渲染區域,而且有一套渲染規則,它決定了其子元素將如何定位,以及和其餘元素的關係和相互做用。flex

那麼 BFC 是什麼呢?spa

BFC 即 Block Formatting Contexts (塊級格式化上下文),它屬於上述定位方案的普通流。3d

具備 BFC 特性的元素能夠看做是隔離了的獨立容器,容器裏面的元素不會在佈局上影響到外面的元素,而且 BFC 具備普通容器所沒有的一些特性。code

通俗一點來說,能夠把 BFC 理解爲一個封閉的大箱子,箱子內部的元素不管如何翻江倒海,都不會影響到外部。orm

觸發 BFC

只要元素知足下面任一條件便可觸發 BFC 特性:cdn

  • body 根元素
  • 浮動元素:float 除 none 之外的值
  • 絕對定位元素:position (absolute、fixed)
  • display 爲 inline-block、table-cell、table-caption、flex等
  • overflow 除了 visible 之外的值 (hidden、auto、scroll)

BFC的做用

  • 清除內部浮動

咱們在佈局時常常會遇到這個問題:對子元素設置浮動後,父元素會發生高度塌陷,也就是父元素的高度變爲0。解決這個問題,只須要把父元素變成一個BFC就好了。經常使用的辦法是給父元素設置overflow:hidden。

<style> .box1{ width:100px; height:100px; float:left; border: 1px solid #000; } .box2{ width:100px; height:100px; float:left; border: 1px solid #000; } .box{ background:yellow } </style>
<body>
    <div class="box">
        <div class="box1"></div>
        <div class="box2"></div>
    </div> 
</body>
複製代碼

因爲容器內兩個div元素浮動,脫離了文檔流,父容器內容寬度爲零(即發生高度塌陷),未能將子元素包裹住。解決這個問題,只須要把把父元素變成一個BFC就好了。經常使用的辦法是給父元素設置overflow:hidden。

  • 垂直margin合併

在CSS當中,相鄰的兩個盒子的外邊距能夠結合成一個單獨的外邊距。這種合併外邊距的方式被稱爲摺疊,而且於是所結合成的外邊距稱爲摺疊外邊距。

摺疊的結果:

  1. 兩個相鄰的外邊距都是正數時,摺疊結果是它們二者之間較大的值。
  2. 兩個相鄰的外邊距都是負數時,摺疊結果是二者絕對值的較大值。
  3. 兩個外邊距一正一負時,摺疊結果是二者的相加的和。

這個一樣能夠利用BFC解決。 若是想要避免外邊距的重疊,能夠將其放在不一樣的 BFC 容器中。

  1. 相鄰兄弟元素margin重疊問題
<style> p{ color: #fff; background: #888; width: 200px; line-height: 100px; text-align:center; margin: 100px; } </style>
<body>
    <p>ABC</p>
    <p>abc</p>
</body>
複製代碼

上面例中兩個P元素之間距離本該爲200px,然而實際上只有100px,發生了margin重疊。遇到這種情形,咱們如何處理? 只須要在p外面包裹一層容器,並觸發該容器生成一個BFC。那麼兩個P便不屬於同一個BFC,就不會發生margin重疊了。

<style> p{ color: #fff; background: #888; width: 200px; line-height: 100px; text-align:center; margin: 100px; } .wrap{ overflow:hidden; } </style>
<body>
  <p>ABC</p>
  <div class="wrap">
    <p>abc</p>
  </div>
</body>
複製代碼

  1. 父子元素margin重疊問題
<style> .box{ width:100px; height:100px; background:#ccc; } .wrap { background:yellow; } .wrap h1{ background:pink; margin:40px; } </style>
<body>
    <div class="box">box</div>
    <div class="wrap">
      <h1>h1</h1>
    </div>
</body>
複製代碼

上圖wrap元素與h1元素之間l理論上本該有個40px的上下margin值,然而實際上父子元素並無存在margin值,與此同時,兩個div元素的間距爲40px。遇到這種情形,咱們如何處理? 處理方法其實有不少,**在wrap元素中添加:overflow:hidden;或者overflow:auto;使其父元素造成一個BFC;也能夠在wrap元素中添加border:1px solid;或是padding:1px;**這些均可以有效解決父子元素margin重疊問題。

  • 建立自適應兩欄佈局

這個方法能夠用來實現兩列自適應佈局,也就是左邊的寬度固定,右邊的寬度自適應。若是咱們改變文字的大小或者左邊浮動元素的大小,兩欄佈局的結構依然沒有改變!

<style> *{ margin: 0; padding: 0; } .box { width:300px; border: 1px solid #000; } .img { float: left; } .info { background: #f1f1f1; color: #222; } </style>
<body>
    <div class="box">
        <img src="03.jpg" alt="" class="img">
        <p class="info">信息信息信息信息信息信息</p>
    </div>
</body>
複製代碼

通常狀況下,它是這樣的

可是當文字多了之後...

顯然,這是文字受到了圖片浮動的影響。固然,若是你想作文本繞排的效果,浮動是不二之選。不過在這裏,這顯然不是咱們想要的。此時咱們能夠爲P元素的內容創建一個BFC,讓其內容消除對外界浮動元素的影響。給文字加上overflow:hidden

兩欄佈局就完成了。咱們改變圖片的大小:

兩欄佈局的結構依然沒有改變,如此就實現了兩欄自適應佈局。

參考連接

相關文章
相關標籤/搜索