開篇
一些元素璧帝,如float元素睬隶,如position為absolute,inline-block,table-cell或table-caption的元素作喘,以及overflow屬性不為visible的元素泞坦,它們將會建立一個新的塊級格式化上下文。
上述定義已經(jīng)很詳細的描述了塊級格式化上下文(Block Formatting Context)是如何形成的赃梧,為了方便起見授嘀,文中均用BFC代替÷嘞眨現(xiàn)在览闰,讓我們用一種簡單的方式對其進行重新定義:
BFC也是HTML中的一個盒子(看不見而已)压鉴,只有滿足至少下列條件之一才能形成BFC:
float屬性不為
none.
position屬性不為
static和relative.
display屬性為下列之一:
table-cell,table-caption,inline-block,flex,or inline-flex.
overflow屬性不為
visible.
讓我們建立一個BFC
HTML代碼如下:
<div class="container">
Some Content here
</div>
我們可以用CSS為container容器附加上述條件,如overflow: scroll, overflow: hidden, display: flex, float: left, or display: table.
盡管這些條件都能形成一個BFC油吭,但是它們各自卻有著不一樣的表現(xiàn):
display: table :
在響應(yīng)式布局中會有問題
overflow: scroll :
可能會出現(xiàn)你不想要的滾動條
float: left:
使元素左浮動婉宰,并且其他元素對其環(huán)繞
overflow: hidden:
消除溢出部分
這么看來心包,建立BFC的最好方式莫過于overflow:hidden
了:
.container {
overflow: hidden;
}
在BFC中缨恒,塊級元素又是怎么布局的呢?
W3C規(guī)范描述如下:
In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).bfcbfc.jpg
![](https://kkkkkxiaofei.github.io/img/bfc/bfc.jpg)
簡單的說:上圖中所有屬于BFC的box都默認左對齊岭佳,并且它們的左邊距可以觸及到容器container的左邊珊随。最后一個box叶洞,盡管它是浮動的禀崖,但它依然遵循這個原則波附。(BFC中的浮動下面會介紹)
-那么,BFC到底有什么卵用呢封寞?
-實際上仅财,真的特別有用
1.利用BFC可以消除Margin Collapse
在正常情況下盏求,在一個容器內(nèi)的所有box將會由上至下依次垂直排列亿眠,即我們所說的一個元素占一行缕探,并切垂直相鄰的距離(即margin)是由各自的margin決定的还蹲,而不是兩個margin的疊加谜喊。
讓我們看一個例子:紅色的div包含三個綠色的p元素倦始。
HTML代碼:
<div class="container">
<p>Sibling 1</p>
<p>Sibling 2</p>
<p>Sibling 3</p>
</div>
CSS代碼:
.container {
background-color: red;
overflow: hidden; /* creates a block formatting context */
}
p {
background-color: lightgreen;
margin: 10px 0;
}
理想情況下鞋邑,我們會認為p標簽之間的margin應(yīng)該是它們的和(20px),但實際上卻是10px.這其實是collapsing margins枚碗。
結(jié)果如下:
![](https://kkkkkxiaofei.github.io/img/bfc/demo1-1.jpg)
這似乎讓人有點困惑,BFC導(dǎo)致了margin collapse遵堵,而現(xiàn)在又要用它來解決margin cllapse.但是始終要記住一點:只有當元素在同一個BFC中時陌宿,垂直方向上的margin
才會clollpase.如果它們屬于不同的BFC波丰,則不會有margin collapse.因此我們可以再建立一個BFC去阻止margin collpase的發(fā)生。
現(xiàn)在HTML變成:
<div class="container">
<p>Sibling 1</p>
<p>Sibling 2</p>
<div class="newBFC">
<p>Sibling 3</p>
</div>
</div>
CSS也有改變:
.container {
background-color: red;
overflow: hidden; /* creates a block formatting context */
}
p {
margin: 10px 0;
background-color: lightgreen;
}
.newBFC {
overflow: hidden; /* creates new block formatting context */
}
現(xiàn)在的結(jié)果為:
![](https://kkkkkxiaofei.github.io/img/bfc/demo1-2.jpg)
由于第二個p元素和第三個p元素屬于不同的BFC,因此避免了margin collapse.
2.利用BFC去容納浮動元素
我相信大家經(jīng)常會遇到一個容器里有浮動元素媚赖,但是這個容器的高度卻是0的場景,如下圖:
看下面的例子:
HTML:
<div class="container">
<div>Sibling</div>
<div>Sibling</div>
</div>
CSS:
.container {
background-color: green;
}
.container div {
float: left;
background-color: lightgreen;
margin: 10px;
}
結(jié)果:
![](https://kkkkkxiaofei.github.io/img/bfc/demo2-2.jpg)
在上邊的情形中颖对,container是不會有高度的缤底,因為它包含了浮動元素。通常我們解決這個問題的辦法是利用一個偽元素去實現(xiàn)clear fix江解,但是現(xiàn)在我們有了更好的解決辦法徙歼,即利用BFC,因為它夠容納浮動元素的桨螺。
我們現(xiàn)在讓container形成BFC規(guī)則灭翔,結(jié)果如下:
.container {
overflow: hidden; /* creates block formatting context */
background-color: green;
}
.container div {
float: left;
background-color: lightgreen;
margin: 10px;
}
結(jié)果:
![](https://kkkkkxiaofei.github.io/img/bfc/demo2-3.jpg)
3.利用BFC阻止文本換行
有時候肝箱,確切的說大多數(shù)情況(若沒有特殊設(shè)置)稀蟋,文本將會環(huán)繞浮動元素(如Figure 1),
但有時候這并不是我們期望的,我們想要的是Figure2唱矛。
![](https://kkkkkxiaofei.github.io/img/bfc/demo3-1.jpg)
往往可能大家都會選擇利用margin-left來強行讓p的容器有一個左邊距绎谦,而距離恰好為Floated div的寬度粥脚,但現(xiàn)在我們可以利用BFC更好的解決這個問題。
首先讓我們了解一下文本換行的原理吧:
![](https://kkkkkxiaofei.github.io/img/bfc/demo3-2.jpg)
在Figure1中冤留,整個p元素實際上是處于上圖中的黑色區(qū)域纤怒,p元素沒有移動是因為它在浮動元素的下方天通。但實際上p作為行塊級別的元素(相對于行內(nèi)文本)卻發(fā)生了移動,因為要給float元素'騰'位置烘豹,而隨著文本的增加,文本高度超過浮動元素的部分則不會在水平方向上收縮內(nèi)部距離携悯,因此看起來像是環(huán)繞。
如圖:
![](https://kkkkkxiaofei.github.io/img/bfc/demo3-3.jpg)
在解決這個問題之前龟劲,我們先來看一下W3C的規(guī)范在這方面的描述:
In a block formatting context, each box’s left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch). This is true even in the presence of floats (although a box’s line boxes may shrink due to the floats), unless the box establishes a new block formatting context (in which case the box itself may become narrower due to the floats).
W3C為這種情況提供了一個解決方案:unless the box establishes a new block formatting context
咸灿,即為p建立BFC。
結(jié)果:
![](https://kkkkkxiaofei.github.io/img/bfc/demo3-4.jpg)