理解BFC

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

你要知道的

在學(xué)習(xí) BFC 之前,你需要知道下面幾個(gè)要點(diǎn):

  • BFC 規(guī)定了瀏覽器對(duì)于元素和子元素渲染方式
  • BFC 是需要觸發(fā)條件的
  • 只有觸發(fā)了 BFC 的元素才能應(yīng)用 BFC 的規(guī)則
  • BFC 元素和 display:block 的元素沒有半毛錢關(guān)系

BFC 的一些特性

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

  • BFC 容器會(huì)阻止外邊距疊加
  • BFC 容器會(huì)阻止其被浮動(dòng)元素覆蓋
  • 計(jì)算 BFC 容器的高度時(shí),會(huì)包含浮動(dòng)元素

這三個(gè)特性可以算是 BFC 中最常用的幾個(gè)特性了,可以幫助我們理解浮動(dòng)、清浮動(dòng)等知識(shí)。

觸發(fā) BFC

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

  • float 設(shè)置為 none 以外的值(left,right
  • overflow 設(shè)置為 visible 以外的值(hidden,auto,scroll
  • position 設(shè)置為 relative 以外的值(absolutefixed
  • display 設(shè)置為 inline-block,table,table-celltable-caption

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

上面的文字引用于那些年我們一起清除過的浮動(dòng)。

應(yīng)用

了解了 BFC 的常用特性以及觸發(fā)條件后,我們可以使用 HTML+CSS 來對(duì)這些理論進(jìn)行驗(yàn)證。下面依次驗(yàn)證這幾個(gè)特性:

BFC 容器會(huì)阻止外邊距疊加

外邊距疊加是在元素在垂直方向上margin值的疊加效應(yīng),我在這篇文章中也做了一些總結(jié),您可以進(jìn)行查看。
1.設(shè)置元素的 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.設(shè)置元素的 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.設(shè)置元素的 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;
}

效果預(yù)覽:

BFC阻止外邊距疊加03.png

4.設(shè)置元素的 position 屬性
使用絕對(duì)定位固定定位的元素脫離了標(biāo)準(zhǔn)文檔流,并且有了層級(jí)的概念,因此其邊距不會(huì)和其他元素的邊距產(chǎn)生疊加效應(yīng)(因?yàn)椴辉谕粋€(gè)層級(jí)),這個(gè)效果不好演示,這里就略過了~

BFC 容器會(huì)阻止其被浮動(dòng)元素覆蓋

我們知道浮動(dòng)元素是一個(gè) BFC 容器,其脫離了標(biāo)準(zhǔn)的文檔流,其后面元素就好像這個(gè)元素不存在一樣。浮動(dòng)元素會(huì)一直想或者向右移動(dòng),直到其碰到了父級(jí)元素或者其他元素的邊緣才停止。
先看一個(gè)簡(jiǎn)單的 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元素阻止浮動(dòng)元素對(duì)齊覆蓋01.png

可見,由于第一個(gè)段落采用了浮動(dòng),便脫離了標(biāo)準(zhǔn)文檔流,其后面的元素就好像這個(gè)浮動(dòng)元素不存在一樣,直接挨著父級(jí)元素排列,所以視覺效果上,后面的那一個(gè)段落被覆蓋掉了。
由于BFC 容器會(huì)阻止其被浮動(dòng)元素覆蓋,因此我們只需要讓后面的段落觸發(fā) BFC 就可以阻止浮動(dòng)元素的覆蓋啦。
1.設(shè)置元素的 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;
}

運(yùn)行效果:

BCF元素阻止浮動(dòng)元素對(duì)齊覆蓋02.png

2.設(shè)置元素的 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;
}

運(yùn)行效果:

BCF元素阻止浮動(dòng)元素對(duì)齊覆蓋03.png

3.設(shè)置元素的 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;
}

運(yùn)行效果:

BCF元素阻止浮動(dòng)元素對(duì)齊覆蓋04.png

4.設(shè)置元素的 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;
}

運(yùn)行效果:

BCF元素阻止浮動(dòng)元素對(duì)齊覆蓋04.png

這個(gè)最霸道,不僅阻止了浮動(dòng)元素對(duì)其自身進(jìn)行覆蓋,反而還把浮動(dòng)元素給覆蓋了,666

計(jì)算 BFC 容器的高度時(shí),會(huì)包含浮動(dòng)元素

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

總結(jié)

本文主要講解了 BFC 的概念,BFC 是 CSS 2.1 中的一項(xiàng)規(guī)范,規(guī)定了其和子元素的一些呈現(xiàn)方式。BFC 需要一些觸發(fā)條件,和浮動(dòng)、定位、行內(nèi)塊等知識(shí)點(diǎn)關(guān)系緊密,需要我們?nèi)ド钊肜斫狻?/p>

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

完。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 14,124評(píng)論 1 92
  • 前言 css一直不是我的強(qiáng)項(xiàng),這也是我第一篇css相關(guān)的文章,雖然我平時(shí)css寫的比較少,但其中比較重要的基礎(chǔ)...
    ITgecko閱讀 508評(píng)論 0 7
  • 先前在學(xué)習(xí)CSS float時(shí),有同學(xué)提到了BFC這個(gè)詞,作為求知好問的好學(xué)生,哪里不懂查哪里,那么今天就來研究一...
    這名字真不對(duì)閱讀 6,684評(píng)論 3 19
  • 1、心情:很好 2、體重:172.3斤 3、血壓:高壓183、低壓113 4、吃飯:今天早餐面窩加米巴、中餐蓋飯、...
    沐沐滿閱讀 555評(píng)論 0 0
  • 凡夢(mèng)!今天天氣很好呀~
    啞覓閱讀 271評(píng)論 0 0

友情鏈接更多精彩內(nèi)容