BFC 的概念始于 CSS2,是個(gè)蠻古老的 CSS 話題了,網(wǎng)上也到處能搜到 BFC 的介紹,但是都不夠簡潔。本文系翻譯自 Rachel Andrew 女士的博文Understanding CSS Layout And The Block Formatting Context ,內(nèi)容足夠簡潔明了。
本文的目的是介紹一些概念,來幫你增強(qiáng) CSS 碼力。如標(biāo)題所示,這篇文章主要是講 塊級(jí)格式上下文(BFC,Block Formatting Context) 。你可能沒聽過這個(gè)術(shù)語,但只要你曾經(jīng)使用 過CSS 布局,你就能明白它。理解 BFC 是什么、它如何工作、如何創(chuàng)建一個(gè) BFC 是非常有用的,這些能幫你更好的理解 CSS 布局。
這篇文章里,我會(huì)通過幾個(gè)你會(huì)很熟悉的的示例解釋 BFC。我還會(huì)告訴你一個(gè)新的 display 值,當(dāng)你理解了 BFC 后可能會(huì)很需要這個(gè)值。
什么是 BFC
一個(gè)簡單的浮動(dòng)的示例就能明白 BFC 的行為,在下面的示例中我們創(chuàng)建一個(gè) box 元素,該元素包裹一段文字和一個(gè)浮動(dòng)的圖片。 如果文字內(nèi)容多的話文字將環(huán)繞著整個(gè)浮動(dòng)圖片,box 的邊框會(huì)把他們整個(gè)包裹起來。
<div class="outer"> <div class="float">I am a floated element.</div> I am text inside the outer box.</div>
.outer { border: 5px dotted rgb(214,129,137); border-radius: 5px; width: 450px; padding: 10px; margin-bottom: 40px;}.float { padding: 10px; border: 5px solid rgba(214,129,137,.4); border-radius: 5px; background-color: rgba(233,78,119,.4); color: #fff; float: left; width: 200px; margin: 0 20px 0 0;}
文字環(huán)繞著浮動(dòng)元素
但如果把一些文字刪除,就沒有足夠的文字去環(huán)繞圖片(浮動(dòng)元素)了,同時(shí)由于浮動(dòng)元素脫離文檔流,box 元素的邊框高度就會(huì)隨文字的減少而降低。
沒有足夠的文字,box 元素邊框的高度就會(huì)低于浮動(dòng)元素的高度
之所以會(huì)發(fā)生這種情況是由于當(dāng)我們浮動(dòng)一個(gè)元素后,box 元素仍然保持原來的寬度,是文字所占的空間縮短了以給浮動(dòng)元素騰出位置,這就是為什么背景和邊框能夠看起來包裹住了浮動(dòng)元素。
我們通常會(huì)使用兩種不同的方式來解決這個(gè)問題,一種是使用clear hack,就是在 文字和圖片的下方插入一個(gè) div 并將它的 CSS clear 屬性設(shè)值為 both 。另外一種方法是使用 overflow 屬性 ,把它設(shè)值成非默認(rèn)值 visible 的值。
.outer { overflow: auto;}
使
用 overflow: auto 后 box 就能包裹浮動(dòng)元素了
overflow 之所以能夠有效是因?yàn)楫?dāng)它的是是非 visible 時(shí)會(huì)創(chuàng)建一個(gè) BFC,而 BFC 的功能之一就是 包裹浮動(dòng)元素 。
BFC 是布局中的迷你布局
你可以把 BFC 當(dāng)做你頁面中的一塊小布局,當(dāng)一個(gè)元素被創(chuàng)建成 BFC 后,它其中的所有元素都會(huì)被它包裹。正如我們所見,當(dāng) box 元素變成 BFC 后,它其中的浮動(dòng)元素就再也沒能突破它的底部。除此之外,BFC 還有一些有用的功能。
BFC 可以阻擋外邊距疊加(margins collapsing)
理解外邊距疊加是另外一個(gè)被低估的 CSS 技巧。在接下來的示例里,我創(chuàng)建了一個(gè)背景灰色的 div,這個(gè) div 含有兩個(gè)段落,div 元素的 margin-bottom 為 40px,同時(shí)每個(gè)段落都有 20px 的 margin-top 與 margin-bottom。
.outer { background-color: #ccc; margin: 0 0 40px 0;}p { padding: 0; margin: 20px 0 20px 0; background-color: rgb(233,78,119); color: #fff;}由于 p 元素的邊緣與 outer 元素的邊緣之間沒有任何東西,所以 outer 與 p 的 margin 會(huì)疊加,p 會(huì)與 outer 的頂部與底部齊平,p 對(duì)外的 margin 似乎與 outer 的 margin 合并了,使我們無法在段落的上下看到 outer 的灰色背景。
由于 margin collapse(外邊距疊加),我們看到 outer 內(nèi)部上下沒有灰色背景
如果我們把 outer 元素變成 BFC,它就可以包裹住 p 以及 p 的 margin,外邊距不會(huì)發(fā)生疊加,outer 元素內(nèi)部就會(huì)出現(xiàn)由 p 元素的 margin 頂出來的上下灰色背景。
.outer { background-color: #ccc; margin: 0 0 40px 0; overflow: auto;}
建立 BFC 后,外邊距不再疊加
一旦 BFC 建立,它就會(huì)阻止它內(nèi)部的元素逃離突破它。
一個(gè) BFC 會(huì)停止去環(huán)繞浮動(dòng)元素
你可能很熟悉 BFC 的這個(gè)特性,我們在有浮動(dòng)元素的列類型布局中常用到。如果一個(gè)元素創(chuàng)建了 BFC,它就不會(huì)去環(huán)繞(或者說包裝?)任何浮動(dòng)元素。看下面這個(gè)示例:
<div class="outer"> <div class="float">I am a floated element.</div> <div class="text">I am text</div></div>
class 名為 float 的元素將會(huì)浮動(dòng)在布局的左側(cè),class 名為 text 的 div 元素將會(huì)在它后面并環(huán)繞它。
文字環(huán)繞著浮動(dòng)元素
我們可以通過給 text 元素建立 BFC 來阻擋這種環(huán)繞行為。
.text { overflow: auto;}
text 元素建立 BFC 后就不再環(huán)繞浮動(dòng)元素了
該方法也是我們創(chuàng)建浮動(dòng)布局的基本方式。還需注意的是浮動(dòng)一個(gè)元素時(shí)也會(huì)給該元素創(chuàng)建 BFC,也就是說此時(shí) .float 與 .text 都是 BFC,這也是無論右側(cè)高度低于還是高于左側(cè)兩者都不會(huì)互相圍繞的原因。
創(chuàng)建一個(gè) BFC 的常用方式
除了使用 overflow 外, 一些其他的 CSS 屬性也可以創(chuàng)建 BFC,比如上面我們所見,浮動(dòng)一個(gè)元素也可以為該元素創(chuàng)建 BFC,浮動(dòng)元素會(huì)包裹它內(nèi)部的所有元素。還有以下幾種方式可以創(chuàng)建 BFC:
使用 position: absolute 或者 position: fixed 。
使用 display: inline-block 、 display: table-cell 或者 display: table-caption ,其中 table-cell 和 table-caption 是表格相關(guān) HTML 元素的對(duì)應(yīng)默認(rèn) CSS 值,所以當(dāng)你創(chuàng)建表格每個(gè)表格單元都會(huì)自動(dòng)創(chuàng)建 BFC。
另外當(dāng)使用 multi-column layout (多列布局)時(shí)使用 colum-span: all 也可以創(chuàng)建 BFC。Flex(彈性) 和 Grid(網(wǎng)格) 布局中的元素也會(huì)自動(dòng)創(chuàng)建類似 BFC 的機(jī)制,只是它們被稱為 Flex Formatting Context(彈性格式上下文)和 Grid Formatting Context(網(wǎng)格格式上下文)。這反映了它們所參與的布局類型。一個(gè) Block Formatting Context(塊級(jí)格式上下文)表明他內(nèi)部的元素參與了塊級(jí)布局,一個(gè) 彈性格式上下文意味著它內(nèi)部的元素參與了彈性布局。在實(shí)踐中,這幾種布局的結(jié)果是相似的,浮動(dòng)元素會(huì)被包裹、外邊距不會(huì)疊加。
創(chuàng)建 BFC 的新方式
使用 overflow 或其他的方法創(chuàng)建 BFC 時(shí)會(huì)有兩個(gè)問題。第一個(gè)是這些方法本身是有自身的設(shè)計(jì)目的的,所以在使用它們創(chuàng)建 BFC 時(shí)會(huì)可能產(chǎn)生副作用。例如使用 overflow 創(chuàng)建 BFC 后在某些情況下你可能會(huì)看到出現(xiàn)一個(gè)滾動(dòng)條或者元素內(nèi)容被削減。這是由于 overflow 屬性是設(shè)計(jì)被用來讓你告訴瀏覽器如何定義元素的溢出狀態(tài)的。瀏覽器執(zhí)行了它最基本的定義。
另一個(gè)問題是,即使在沒有出現(xiàn)副作用的情況下,使用 overflow 也可能會(huì)使另一個(gè)開發(fā)人員感到困惑。他們可能會(huì)各種猜想:這里為啥要把 overflow 的值設(shè)為 auto 或 scroll?原開發(fā)人員做這個(gè)意義何在?原開發(fā)人員是想讓這里出現(xiàn)滾動(dòng)條嗎?
最安全的做法應(yīng)該是創(chuàng)建一個(gè) BFC 時(shí)不會(huì)有任何副作用,它內(nèi)部的元素都安安全全的呆在這個(gè)小布局里,這種方法不會(huì)引起任何意想不到的問題,也可以讓開發(fā)者意圖清晰。CSS 工作組也十分認(rèn)同這種想法,所以他們定制了一個(gè)新的屬性值: display: flow-root 。
你可以使用 display: flow-root 安全的創(chuàng)建 BFC 來解決本文中提到的各種問題,包括:包裹浮動(dòng)元素、阻止外邊距疊加、阻止環(huán)繞浮動(dòng)元素。
caniuse 上 display: flow-root 各瀏覽器支持情況
瀏覽器對(duì)該屬性值的支持目前還是有限的,如果你覺得這個(gè)屬性值很方便,請投票去讓 Edge 也支持它。不過無論如何,你現(xiàn)在應(yīng)該已經(jīng)理解了什么是 BFC,以及如何使用 overflow 或其他方法來包裹浮動(dòng),以及知道了 BFC 可以阻止元素去環(huán)繞浮動(dòng)元素,如果你想使用彈性或網(wǎng)格布局可以在一些不支持他們的瀏覽器中使用 BFC 的這些特性做降級(jí)處理。
理解瀏覽器如何布置網(wǎng)頁是非常基礎(chǔ)的。 雖然有時(shí)看起來無關(guān)緊要,但是這些小知識(shí)可以加快創(chuàng)建和調(diào)試 CSS 布局所需的時(shí)間。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。
新聞熱點(diǎn)
疑難解答
圖片精選