注:本文首發於我的博客 www.ferecord.com/understandi…,如若轉載請註明來源。css
BFC 的概念始於 CSS2,是個蠻古老的 CSS 話題了,網上也處處能搜到 BFC 的介紹,可是都不夠簡潔。本文系翻譯自 Rachel Andrew 女士的博文 Understanding CSS Layout And The Block Formatting Context,內容足夠簡潔明瞭。html
本文的目的是介紹一些概念,來幫你加強 CSS 碼力。如標題所示,這篇文章主要是講塊級格式上下文(BFC,Block Formatting Context)。你可能沒聽過這個術語,但只要你曾經使用 過CSS 佈局,你就能明白它。理解 BFC 是什麼、它如何工做、如何建立一個 BFC 是很是有用的,這些能幫你更好的理解 CSS 佈局。瀏覽器
這篇文章裏,我會經過幾個你會很熟悉的的示例解釋 BFC。我還會告訴你一個新的 display 值,當你理解了 BFC 後可能會很須要這個值。安全
一個簡單的浮動的示例就能明白 BFC 的行爲,在下面的示例中咱們建立一個 box 元素,該元素包裹一段文字和一個浮動的圖片。 若是文字內容多的話文字將環繞着整個浮動圖片,box 的邊框會把他們整個包裹起來。ide
<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;
}
複製代碼
但若是把一些文字刪除,就沒有足夠的文字去環繞圖片(浮動元素)了,同時因爲浮動元素脫離文檔流,box 元素的邊框高度就會隨文字的減小而下降。佈局
之因此會發生這種狀況是因爲當咱們浮動一個元素後,box 元素仍然保持原來的寬度,是文字所佔的空間縮短了以給浮動元素騰出位置,這就是爲何背景和邊框可以看起來包裹住了浮動元素。spa
咱們一般會使用兩種不一樣的方式來解決這個問題,一種是使用 clear hack,就是在 文字和圖片的下方插入一個 div 並將它的 CSS clear
屬性設值爲 both
。另一種方法是使用 overflow
屬性 ,把它設值成非默認值 visible
的值。翻譯
.outer {
overflow: auto;
}
複製代碼
overflow: auto
後 box 就能包裹浮動元素了
overflow 之因此可以有效是由於當它的是是非 visible
時會建立一個 BFC,而 BFC 的功能之一就是包裹浮動元素。設計
你能夠把 BFC 當作你頁面中的一塊小布局,當一個元素被建立成 BFC 後,它其中的全部元素都會被它包裹。正如咱們所見,當 box 元素變成 BFC 後,它其中的浮動元素就再也沒能突破它的底部。除此以外,BFC 還有一些有用的功能。3d
BFC 能夠阻擋外邊距疊加(margins collapsing)
理解外邊距疊加是另一個被低估的 CSS 技巧。在接下來的示例裏,我建立了一個背景灰色的 div,這個 div 含有兩個段落,div 元素的 margin-bottom 爲 40px,同時每一個段落都有 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 會疊加,p 會與 outer 的頂部與底部齊平,p 對外的 margin 彷佛與 outer 的 margin 合併了,使咱們沒法在段落的上下看到 outer 的灰色背景。
若是咱們把 outer 元素變成 BFC,它就能夠包裹住 p 以及 p 的 margin,外邊距不會發生疊加,outer 元素內部就會出現由 p 元素的 margin 頂出來的上下灰色背景。
.outer {
background-color: #ccc;
margin: 0 0 40px 0;
overflow: auto;
}
複製代碼
一旦 BFC 創建,它就會阻止它內部的元素逃離突破它。
一個 BFC 會中止去環繞浮動元素
你可能很熟悉 BFC 的這個特性,咱們在有浮動元素的列類型佈局中經常使用到。若是一個元素建立了 BFC,它就不會去環繞(或者說包裝?)任何浮動元素。看下面這個示例:
<div class="outer">
<div class="float">I am a floated element.</div>
<div class="text">I am text</div>
</div>
複製代碼
class 名爲 float 的元素將會浮動在佈局的左側,class 名爲 text 的 div 元素將會在它後面並環繞它。
咱們能夠經過給 text 元素創建 BFC 來阻擋這種環繞行爲。
.text {
overflow: auto;
}
複製代碼
該方法也是咱們建立浮動佈局的基本方式。還需注意的是浮動一個元素時也會給該元素建立 BFC,也就是說此時 .float 與 .text 都是 BFC,這也是不管右側高度低於仍是高於左側二者都不會互相圍繞的緣由。
除了使用 overflow
外, 一些其餘的 CSS 屬性也能夠建立 BFC,好比上面咱們所見,浮動一個元素也能夠爲該元素建立 BFC,浮動元素會包裹它內部的全部元素。還有如下幾種方式能夠建立 BFC:
使用 position: absolute
或者 position: fixed
。
使用 display: inline-block
、display: table-cell
或者 display: table-caption
,其中 table-cell
和 table-caption
是表格相關 HTML 元素的對應默認 CSS 值,因此當你建立表格每一個表格單元都會自動建立 BFC。
另外當使用 multi-column layout (多列布局)時使用 colum-span: all
也能夠建立 BFC。Flex(彈性) 和 Grid(網格) 佈局中的元素也會自動建立相似 BFC 的機制,只是它們被稱爲 Flex Formatting Context(彈性格式上下文)和 Grid Formatting Context(網格格式上下文)。這反映了它們所參與的佈局類型。一個 Block Formatting Context(塊級格式上下文)代表他內部的元素參與了塊級佈局,一個 彈性格式上下文意味着它內部的元素參與了彈性佈局。在實踐中,這幾種佈局的結果是類似的,浮動元素會被包裹、外邊距不會疊加。
使用 overflow 或其餘的方法建立 BFC 時會有兩個問題。第一個是這些方法自己是有自身的設計目的的,因此在使用它們建立 BFC 時會可能產生反作用。例如使用 overflow 建立 BFC 後在某些狀況下你可能會看到出現一個滾動條或者元素內容被削減。這是因爲 overflow 屬性是設計被用來讓你告訴瀏覽器如何定義元素的溢出狀態的。瀏覽器執行了它最基本的定義。
另外一個問題是,即便在沒有出現反作用的狀況下,使用 overflow 也可能會使另外一個開發人員感到困惑。他們可能會各類猜測:這裏爲啥要把 overflow 的值設爲 auto 或 scroll?原開發人員作這個意義何在?原開發人員是想讓這裏出現滾動條嗎?
最安全的作法應該是建立一個 BFC 時不會有任何反作用,它內部的元素都安安全全的呆在這個小布局裏,這種方法不會引發任何意想不到的問題,也可讓開發者意圖清晰。CSS 工做組也十分認同這種想法,因此他們定製了一個新的屬性值:display: flow-root
。
你可使用 display: flow-root
安全的建立 BFC 來解決本文中提到的各類問題,包括:包裹浮動元素、阻止外邊距疊加、阻止環繞浮動元素。
瀏覽器對該屬性值的支持目前仍是有限的,若是你以爲這個屬性值很方便,請投票去讓 Edge 也支持它。不過不管如何,你如今應該已經理解了什麼是 BFC,以及如何使用 overflow 或其餘方法來包裹浮動,以及知道了 BFC 能夠阻止元素去環繞浮動元素,若是你想使用彈性或網格佈局能夠在一些不支持他們的瀏覽器中使用 BFC 的這些特性作降級處理。
理解瀏覽器如何佈置網頁是很是基礎的。 雖然有時看起來可有可無,可是這些小知識能夠加快建立和調試 CSS 佈局所需的時間。