如何理解 CSS 布局和塊級(jí)格式上下文

BFC 的概念始于 CSS2,是個(gè)蠻古老的 CSS 話(huà)題了,網(wǎng)上也到處能搜到 BFC 的介紹,但是都不夠簡(jiǎn)潔。本文系翻譯自 Rachel Andrew 女士的博文Understanding CSS Layout And The Block Formatting Context ,內(nèi)容足夠簡(jiǎn)潔明了。
本文的目的是介紹一些概念,來(lái)幫你增強(qiáng) CSS 碼力。如標(biāo)題所示,這篇文章主要是講 塊級(jí)格式上下文(BFC,Block Formatting Context) 。你可能沒(méi)聽(tīng)過(guò)這個(gè)術(shù)語(yǔ),但只要你曾經(jīng)使用 過(guò)CSS 布局,你就能明白它。理解 BFC 是什么、它如何工作、如何創(chuàng)建一個(gè) BFC 是非常有用的,這些能幫你更好的理解 CSS 布局。
這篇文章里,我會(huì)通過(guò)幾個(gè)你會(huì)很熟悉的的示例解釋 BFC。我還會(huì)告訴你一個(gè)新的 display 值,當(dāng)你理解了 BFC 后可能會(huì)很需要這個(gè)值。
什么是 BFC
一個(gè)簡(jiǎn)單的浮動(dòng)的示例就能明白 BFC 的行為,在下面的示例中我們創(chuàng)建一個(gè) box 元素,該元素包裹一段文字和一個(gè)浮動(dòng)的圖片。 如果文字內(nèi)容多的話(huà)文字將環(huán)繞著整個(gè)浮動(dòng)圖片,box 的邊框會(huì)把他們整個(gè)包裹起來(lái)。
<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)元素
但如果把一些文字刪除,就沒(méi)有足夠的文字去環(huán)繞圖片(浮動(dòng)元素)了,同時(shí)由于浮動(dòng)元素脫離文檔流,box 元素的邊框高度就會(huì)隨文字的減少而降低。
沒(méi)有足夠的文字,box 元素邊框的高度就會(huì)低于浮動(dòng)元素的高度
之所以會(huì)發(fā)生這種情況是由于當(dāng)我們浮動(dòng)一個(gè)元素后,box 元素仍然保持原來(lái)的寬度,是文字所占的空間縮短了以給浮動(dòng)元素騰出位置,這就是為什么背景和邊框能夠看起來(lái)包裹住了浮動(dòng)元素。
我們通常會(huì)使用兩種不同的方式來(lái)解決這個(gè)問(wèn)題,一種是使用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)做你頁(yè)面中的一塊小布局,當(dāng)一個(gè)元素被創(chuàng)建成 BFC 后,它其中的所有元素都會(huì)被它包裹。正如我們所見(jiàn),當(dāng) box 元素變成 BFC 后,它其中的浮動(dòng)元素就再也沒(méi)能突破它的底部。除此之外,BFC 還有一些有用的功能。
BFC 可以阻擋外邊距疊加(margins collapsing)
理解外邊距疊加是另外一個(gè)被低估的 CSS 技巧。在接下來(lái)的示例里,我創(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 元素的邊緣之間沒(méi)有任何東西,所以 outer 與 p 的 margin 會(huì)疊加,p 會(huì)與 outer 的頂部與底部齊平,p 對(duì)外的 margin 似乎與 outer 的 margin 合并了,使我們無(wú)法在段落的上下看到 outer 的灰色背景。
由于 margin collapse(外邊距疊加),我們看到 outer 內(nèi)部上下沒(méi)有灰色背景
如果我們把 outer 元素變成 BFC,它就可以包裹住 p 以及 p 的 margin,外邊距不會(huì)發(fā)生疊加,outer 元素內(nèi)部就會(huì)出現(xiàn)由 p 元素的 margin 頂出來(lái)的上下灰色背景。
.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è)特性,我們?cè)谟懈?dòng)元素的列類(lèi)型布局中常用到。如果一個(gè)元素創(chuàng)建了 BFC,它就不會(huì)去環(huán)繞(或者說(shuō)包裝?)任何浮動(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)元素
我們可以通過(guò)給 text 元素建立 BFC 來(lái)阻擋這種環(huán)繞行為。
.text { overflow: auto; }
text 元素建立 BFC 后就不再環(huán)繞浮動(dòng)元素了
該方法也是我們創(chuàng)建浮動(dòng)布局的基本方式。還需注意的是浮動(dòng)一個(gè)元素時(shí)也會(huì)給該元素創(chuàng)建 BFC,也就是說(shuō)此時(shí) .float 與 .text 都是 BFC,這也是無(wú)論右側(cè)高度低于還是高于左側(cè)兩者都不會(huì)互相圍繞的原因。
創(chuàng)建一個(gè) BFC 的常用方式
除了使用 overflow
外, 一些其他的 CSS 屬性也可以創(chuàng)建 BFC,比如上面我們所見(jiàn),浮動(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)建類(lèi)似 BFC 的機(jī)制,只是它們被稱(chēng)為 Flex Formatting Context(彈性格式上下文)和 Grid Formatting Context(網(wǎng)格格式上下文)。這反映了它們所參與的布局類(lèi)型。一個(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è)問(wèn)題。第一個(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ì)被用來(lái)讓你告訴瀏覽器如何定義元素的溢出狀態(tài)的。瀏覽器執(zhí)行了它最基本的定義。
另一個(gè)問(wèn)題是,即使在沒(méi)有出現(xiàn)副作用的情況下,使用 overflow 也可能會(huì)使另一個(gè)開(kāi)發(fā)人員感到困惑。他們可能會(huì)各種猜想:這里為啥要把 overflow 的值設(shè)為 auto 或 scroll?原開(kāi)發(fā)人員做這個(gè)意義何在?原開(kāi)發(fā)人員是想讓這里出現(xiàn)滾動(dòng)條嗎?
最安全的做法應(yīng)該是創(chuàng)建一個(gè) BFC 時(shí)不會(huì)有任何副作用,它內(nèi)部的元素都安安全全的呆在這個(gè)小布局里,這種方法不會(huì)引起任何意想不到的問(wèn)題,也可以讓開(kāi)發(fā)者意圖清晰。CSS 工作組也十分認(rèn)同這種想法,所以他們定制了一個(gè)新的屬性值: display: flow-root
。
你可以使用 display: flow-root
安全的創(chuàng)建 BFC 來(lái)解決本文中提到的各種問(wèn)題,包括:包裹浮動(dòng)元素、阻止外邊距疊加、阻止環(huán)繞浮動(dòng)元素。
caniuse 上 display: flow-root 各瀏覽器支持情況
瀏覽器對(duì)該屬性值的支持目前還是有限的,如果你覺(jué)得這個(gè)屬性值很方便,請(qǐng)投票去讓 Edge 也支持它。不過(guò)無(wú)論如何,你現(xiàn)在應(yīng)該已經(jīng)理解了什么是 BFC,以及如何使用 overflow 或其他方法來(lái)包裹浮動(dòng),以及知道了 BFC 可以阻止元素去環(huán)繞浮動(dòng)元素,如果你想使用彈性或網(wǎng)格布局可以在一些不支持他們的瀏覽器中使用 BFC 的這些特性做降級(jí)處理。
理解瀏覽器如何布置網(wǎng)頁(yè)是非?;A(chǔ)的。 雖然有時(shí)看起來(lái)無(wú)關(guān)緊要,但是這些小知識(shí)可以加快創(chuàng)建和調(diào)試 CSS 布局所需的時(shí)間。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解css布局實(shí)現(xiàn)左中右布局的5種方式
這篇文章主要介紹了詳解css布局實(shí)現(xiàn)左中右布局的5種方式的相關(guān)資料,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-05CSS實(shí)現(xiàn)多行多列的布局的實(shí)例代碼
這篇文章主要介紹了CSS實(shí)現(xiàn)多行多列的布局的實(shí)例代碼,需要的朋友可以參考下2018-02-28- 這篇文章主要介紹了css Flex布局的可伸縮性(Flexibility)的相關(guān)資料,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-07
- 這篇文章主要介紹了淺談css網(wǎng)頁(yè)的幾種布局的相關(guān)資料,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-08
- 本篇文章主要介紹了css sticker-footer 布局,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-06
詳解使用CSS3的@media來(lái)編寫(xiě)響應(yīng)式的頁(yè)面
這篇文章主要介紹了詳解使用CSS3的@media來(lái)編寫(xiě)響應(yīng)式的頁(yè)面,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-01- 這篇文章主要介紹了CSS布局方案小結(jié),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2018-03-13