理解BFC

BFC 的全稱是 Block Formating Context,譯為“塊級格式化上下文”,是 CSS 規范中的一個概念,規定了一套渲染規則,規定了內部的子元素如何布局,以及他們和其他元素的關系等。
除了 BFC 之外,規范中還有 IFC 的概念,也就是 Inline Formating Context,譯為“內聯格式化上下文”。
BFC 和 IFC 都是 CSS 2.1 中的規范,在 CSS3 中,還有 GFC、FFC 等。
本文的重點是對 BFC 的理解,理解了 BFC 之后,就對 CSS 中的很多東西有了原理化的認知,更加明白 CSS 中的一些難點特性,如浮動、定位等。

你要知道的

在學習 BFC 之前,你需要知道下面幾個要點:

  • BFC 規定了瀏覽器對于元素和子元素渲染方式
  • BFC 是需要觸發條件的
  • 只有觸發了 BFC 的元素才能應用 BFC 的規則
  • BFC 元素和 display:block 的元素沒有半毛錢關系

BFC 的一些特性

BFC 包含以下一些常用特性:

  • BFC 容器會阻止外邊距疊加
  • BFC 容器會阻止其被浮動元素覆蓋
  • 計算 BFC 容器的高度時,會包含浮動元素

這三個特性可以算是 BFC 中最常用的幾個特性了,可以幫助我們理解浮動、清浮動等知識。

觸發 BFC

滿足下列任意條件,就可以觸發 BFC:

  • float 設置為 none 以外的值(leftright
  • overflow 設置為 visible 以外的值(hiddenautoscroll
  • position 設置為 relative 以外的值(absolutefixed
  • display 設置為 inline-blocktabletable-celltable-caption

需要注意的是,display:table 本身并不會創建BFC,但是它會產生匿名框(anonymous boxes),而匿名框中的display:table-cell可以創建新的BFC,換句話說,觸發塊級格式化上下文的是匿名框,而不是display:table。所以通過display:table和display:table-cell創建的BFC效果是不一樣的。

上面的文字引用于那些年我們一起清除過的浮動

應用

了解了 BFC 的常用特性以及觸發條件后,我們可以使用 HTML+CSS 來對這些理論進行驗證。下面依次驗證這幾個特性:

BFC 容器會阻止外邊距疊加

外邊距疊加是在元素在垂直方向上margin值的疊加效應,我在這篇文章中也做了一些總結,您可以進行查看。
1.設置元素的 float 屬性
HTML 代碼:

<div>
    <p></p>
    <p></p>
</div>

CSS 代碼:

div{
    height: 20em;
    border: .1em dashed #ccc;
}
p{
    margin: 0;
    width: 5em;
    height: 5em;
    background: red;
}
p:first-of-type{
    margin-bottom:5em ;
}
p:last-of-type{
    float: left;
    background: blue;
    margin-top: 5em;
}

效果如下:

BFC阻止外邊距疊加01.png

2.設置元素的 overflow 屬性
HTML 代碼:

<div>
    <p></p>
</div>
<p></p>

CSS 代碼:

div{
    overflow: hidden;
}
p{
    margin: 0;
    width: 5em;
    height: 5em;
    margin-top: 5em;
    background: red;
}
div > p{
    margin-bottom:5em ;
    margin-top: 0;
    background: blue;
}

效果展示:

BFC阻止外邊距疊加02.png

3.設置元素的 display 屬性
HTML 代碼:

<div>
    <p></p>
</div>
<p></p>

CSS 代碼:

div{
    display: table-cell;
}
p{
    margin: 0;
    width: 5em;
    height: 5em;
    margin-top: 5em;
    background: red;
}
div > p{
    margin-bottom:5em ;
    margin-top: 0;
    background: blue;
}

效果預覽:

BFC阻止外邊距疊加03.png

4.設置元素的 position 屬性
使用絕對定位固定定位的元素脫離了標準文檔流,并且有了層級的概念,因此其邊距不會和其他元素的邊距產生疊加效應(因為不在同一個層級),這個效果不好演示,這里就略過了~

BFC 容器會阻止其被浮動元素覆蓋

我們知道浮動元素是一個 BFC 容器,其脫離了標準的文檔流,其后面元素就好像這個元素不存在一樣。浮動元素會一直想或者向右移動,直到其碰到了父級元素或者其他元素的邊緣才停止。
先看一個簡單的 Demo:
HTML 代碼:

<div>
    <p></p>
    <p></p>
</div>

CSS 代碼:

div{
    width: 20em;
    height: 5em;
    border: 1px dashed #ccc;
}
p{
    width: 5em;
    height: 5em;
    margin: 0;
}

div >p:first-of-type{
    background: red;
    float: left;
}

div >p:last-of-type{
    background: blue;
    width: 10em
}

展示效果:

BCF元素阻止浮動元素對齊覆蓋01.png

可見,由于第一個段落采用了浮動,便脫離了標準文檔流,其后面的元素就好像這個浮動元素不存在一樣,直接挨著父級元素排列,所以視覺效果上,后面的那一個段落被覆蓋掉了。
由于BFC 容器會阻止其被浮動元素覆蓋,因此我們只需要讓后面的段落觸發 BFC 就可以阻止浮動元素的覆蓋啦。
1.設置元素的 float 屬性
CSS 代碼:

div{
    width: 20em;
    height: 5em;
    border: 1px dashed #ccc;
}
p{
    width: 5em;
    height: 5em;
    margin: 0;
}

div >p:first-of-type{
    background: red;
    float: left;
}

div >p:last-of-type{
    background: blue;
    width: 10em;
    float: left;
}

運行效果:

BCF元素阻止浮動元素對齊覆蓋02.png

2.設置元素的 overflow 屬性
CSS 代碼:

div{
    width: 20em;
    height: 5em;
    border: 1px dashed #ccc;
}
p{
    width: 5em;
    height: 5em;
    margin: 0;
}

div >p:first-of-type{
    background: red;
    float: left;
}

div >p:last-of-type{
    background: blue;
    width: 10em;
    overflow: hidden;
}

運行效果:

BCF元素阻止浮動元素對齊覆蓋03.png

3.設置元素的 display 屬性
CSS 代碼:

div{
    width: 20em;
    height: 5em;
    border: 1px dashed #ccc;
}
p{
    width: 5em;
    height: 5em;
    margin: 0;
}

div >p:first-of-type{
    background: red;
    float: left;
}

div >p:last-of-type{
    background: blue;
    width: 10em;
    display: inline-block;
}

運行效果:

BCF元素阻止浮動元素對齊覆蓋04.png

4.設置元素的 position 屬性
CSS 代碼:

div{
    width: 20em;
    height: 5em;
    border: 1px dashed #ccc;
}
p{
    width: 5em;
    height: 5em;
    margin: 0;
}

div >p:first-of-type{
    background: red;
    float: left;
}

div >p:last-of-type{
    background: blue;
    width: 10em;
    position: absolute;
}

運行效果:

BCF元素阻止浮動元素對齊覆蓋04.png

這個最霸道,不僅阻止了浮動元素對其自身進行覆蓋,反而還把浮動元素給覆蓋了,666

計算 BFC 容器的高度時,會包含浮動元素

這也就是清除浮動的原理了,因為浮動會將元素的 inline-box 設置為0,而我們知道 containing-box 的高度本質上是由 inline-box 決定的(您可以參考這篇文章,里面進行了一些總結),所以如果一個元素中的元素都進行了浮動,那么這個完成元素的高度就塌陷了。為了解決這個問題,我們只需要“找回”外層元素的高度就可以了,運用到的就是 BFC 的這個特性:計算 BFC 容器的高度時,會包含浮動元素。
關于浮動這一塊,里面又有很多概念,需要再用一片文章來寫,這里就不再往下寫了。后面會出一篇和浮動有關的文章,再進行說明。

總結

本文主要講解了 BFC 的概念,BFC 是 CSS 2.1 中的一項規范,規定了其和子元素的一些呈現方式。BFC 需要一些觸發條件,和浮動、定位、行內塊等知識點關系緊密,需要我們去深入理解。

附:參考資料
那些年我們一起清除過的浮動
理解 BFC (Block Formatting Model)
CSS之BFC詳解
深度理解現代瀏覽器中的BFC和IE下的haslayout

完。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,801評論 1 92
  • 前言 css一直不是我的強項,這也是我第一篇css相關的文章,雖然我平時css寫的比較少,但其中比較重要的基礎...
    ITgecko閱讀 415評論 0 7
  • 先前在學習CSS float時,有同學提到了BFC這個詞,作為求知好問的好學生,哪里不懂查哪里,那么今天就來研究一...
    這名字真不對閱讀 6,577評論 3 19
  • 1、心情:很好 2、體重:172.3斤 3、血壓:高壓183、低壓113 4、吃飯:今天早餐面窩加米巴、中餐蓋飯、...
    沐沐滿閱讀 480評論 0 0
  • 凡夢!今天天氣很好呀~
    啞覓閱讀 252評論 0 0