一何鸡、BFC是什么?
它是 Block Formatting Context (塊級格式化上下文) 的簡稱牛欢,接下來通過對其中幾個名詞的解釋進一步了解 BFC 定義音比。
-
Box : CSS布局的基本單位
Box 是 CSS 布局的對象和基本單位, 直觀點來說氢惋,就是一個頁面是由很多個 Box 組成的。元素的類型和display
屬性稽犁,決定了這個 Box 的類型焰望。不同類型的 Box, 會參與不同的 Formatting Context(一個決定如何渲染文檔的容器)已亥,因此Box內的元素會以不同的方式渲染熊赖。
-
幾個常見的盒子:
block-level box:display
屬性為block
,list-item
,table
的元素,會生成 block-level box虑椎。并且參與 block fomatting context震鹉;
inline-level box:display
屬性為inline
,inline-block
,inline-table
的元素,會生成 inline-level box捆姜。并且參與 inline formatting context传趾;
Formatting context
Formatting context 是指頁面中的一塊渲染區(qū)域,并且有一套渲染規(guī)則泥技,它決定了其子元素將如何定位浆兰,以及和其他元素的關系和相互作用。最常見的 Formatting context 有 Block fomatting context (簡稱 BFC )和 Inline formatting context (簡稱 IFC )珊豹。-
**BFC **:塊級格式化上下文
BFC 是指一個獨立的塊級渲染區(qū)域簸呈,只有Block-level Box參與,該區(qū)域擁有一套渲染規(guī)則來約束塊級盒子的布局店茶,且與區(qū)域外部無關蜕便。- BFC就是一種布局方式,可以理解為一個作用范圍贩幻,即在一個BFC里的布局與其之外的布局不相關或者說不相互影響轿腺。
-
舉一個形象的例子:
可以把一個頁面想象成大的集裝箱,這個集裝箱里裝的貨物就是html
元素丛楚。在現實生活中為了避免不同人的貨物相互混淆吃溅,都是把貨物打好包裝再裝入集裝箱,這樣的話無論你包裝里面的貨物怎么擺放鸯檬,都不會影響到其他人的貨物决侈。那么這個包裝就可以被想象成 Block Formatting Context。
4. 為什么要用BFC?
- 使用一定的CSS聲明可以生成BFC赖歌,瀏覽器對生成的BFC有一系列的渲染規(guī)則枉圃,利用這些渲染規(guī)則我們可以達到一定的布局效果,為了達到特定的布局效果我們讓元素生成BFC庐冯。
二孽亲、哪些元素會生成BFC?
當一個HTML元素滿足下面條件的任何一點,都可以產生 Block Formatting Context
根元素
float
的值不為none
展父;overflow
的值不為visible
(可以為hidden
,scroll
,auto
)返劲;display
的值為inline-block
,table-cell
,table-caption
,flex
,inline-flex
中的任何一個;position
的值為absolute
,fixed
(不為static
,relative
中的任何一個)栖茉;display
:table
也認為可以生成BFC篮绿,其實這里的主要原因在于table
會默認生成一個匿名的table-cell
,正是這個匿名的table-cell
生成了BFC吕漂。常用的用來觸發(fā)BFC的CSS樣式:
overflow: scroll
,overflow: hidden
,display: flex
,float: left
,display: table
其中可能產生的一些問題
display:table
—— 可能會產生一些問題overflow:scroll
—— 可能會顯示不必要的滾動條overflow:hidden
—— 將會剪切掉溢出的元素float:left
—— 將會把元素置于容器的左邊亲配,其他元素環(huán)繞著它
三、BFC的布局規(guī)則
- 內部的Box會在垂直方向上一個接一個的放置惶凝;
- 垂直方向上的距離有
margin
決定吼虎。(完整的說法是:屬于同一個BFC的兩個相鄰的Box的margin
會發(fā)生重疊,與方向無關) - 每個盒子的左外邊框緊挨著包含塊的左邊框(從右到左的格式苍鲜,則為緊挨右邊框)思灰,即使浮動元素也是如此。(這說明BFC中的子元素不會超出它的包含塊)
- BFC的區(qū)域不會與
float
的元素區(qū)域重疊 - 計算BFC的高度時混滔,浮動子元素也參與計算官辈;
- BFC就是頁面上的一個隔離的獨立容器绕德,容器里面的子元素不會影響到外面的元素颅夺,反之亦然;
四调榄、BFC的作用及原理
-
自適應兩欄布局
body { width: 300px; }
.aside { width: 100px; height: 150px; float: left; background: #f66; }
.main { height: 200px; background: #fcc; }
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
-
效果圖如下:
分析:
根據BFC布局規(guī)則 第3條:
* 每個元素的margin box的左邊愿伴, 與包含塊border box的左邊相接觸(對于從左往右的格式化肺魁,否則相反),即使存在浮動也是如此隔节。
現象:雖然存在浮動的元素 aside鹅经,但 main 的左邊依然會與包含塊的左邊相接觸。
- 修改:
根據BFC布局規(guī)則第四條:
* BFC的區(qū)域不會與float box重疊怎诫。
改變方法:我們可以通過觸發(fā) main 生成BFC瘾晃, 來實現自適應兩欄布局,當觸發(fā)main 生成BFC后幻妓,這個新的BFC不會與浮動的 aside 重疊蹦误,main 會根據包含塊的寬度,和 aside 的寬度,自動變窄强胰。(一個盒子的邊框會由于浮動而收縮舱沧,盒子本身將會變得更窄)
.main { overflow: hidden;} //或者利用上述其他方式為它生成 BFC
-
新的效果圖如下:
-
清除內部浮動
.par { border: 5px solid #fcc; width: 300px; }
.child { border: 5px solid #f66; width: 100px; height: 100px; float: left;}
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
-
效果圖如下:
修改:
根據BFC布局規(guī)則第五條:
* 計算BFC的高度時,浮動元素也參與計算
**改變方法:**為達到清除內部浮動偶洋,我們可以觸發(fā) par 生成BFC熟吏,那么 par 在計算高度時,par 內部的浮動元素 child 也會參與計算玄窝。
.par { overflow: hidden;} //或者利用上述其他方式為它生成 BFC
-
新的效果圖如下:
-
防止垂直 margin 重疊
<style>
p { color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align: center;
margin: 100px;
}
</style>
<body>
<p>Haha</p>
<p>Hehe</p>
</body>
-
效果圖如下:
分析:
根據BFC布局規(guī)則第二條:
Box垂直方向的距離由margin決定牵寺。屬于同一個BFC的兩個相鄰Box的margin會發(fā)生重疊
現象:兩個p之間的距離為100px,發(fā)送了margin重疊恩脂。
- 修改:
我們可以在p外面包裹一層容器帽氓,并觸發(fā)該容器生成一個BFC。那么兩個P便不屬于同一個BFC东亦,就不會發(fā)生margin重疊了。
<style>
.wrap { overflow: hidden; }
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align: center;
margin: 100px;
}
</style>
<body>
<p>Haha</p>
<div class="wrap">
<p>Hehe</p>
</div>
</body>
-
新的效果圖如下:
其實以上的幾個例子都體現了BFC布局規(guī)則第六條:
- BFC就是頁面上的一個隔離的獨立容器唬渗,容器里面的子元素不會影響到外面的元素典阵。反之也如此。
解釋:
因為BFC內部的元素和外部的元素絕對不會互相影響镊逝;
因此壮啊,** 當BFC外部存在浮動時,它不應該影響B(tài)FC內部Box的布局撑蒜,BFC會通過變窄歹啼,而不與浮動有重疊;
同樣的座菠,當BFC內部有浮動時**狸眼,為了不影響外部元素的布局,BFC計算高度時會包括浮動的高度浴滴;避免margin重疊也是這樣的一個道理拓萌。
五、詳細分析 margin 折疊
1升略、產生的原因
這些
margin
都處于普通流中微王,并在同一個BFC中這些
margin
沒有被非空內容、padding
品嚣、border
或clear
分隔開這些
margin
在垂直方向上是毗鄰的-
2炕倘、包含的情況:
- 一個box的
margin-top
與第一個子box的margin-top
- 一個box的
margin-bottom
與最后一個子box的margin-bottom
,但須在該box的height:auto
的情況下 - 一個box的
margin-bottom
與緊接著的下一個box的margin-top
- 一個box的
margin-top
與其自身的margin-bottom
翰撑,但須滿足沒創(chuàng)建BFC
注:另一篇CSS盒子對這些情況有圖解
- 一個box的
3罩旋、折疊邊距的計算
當兩個margin都是正值的時候,取兩者的最大值;
當 margin 都是負值的時候瘸恼,取的是其中絕對值較大的劣挫,然后,從 0 位置东帅,負向位移压固;
當有正有負的時候,先取出負 margin 中絕對值中最大的靠闭,然后帐我,和正 margin 值中最大的 margin 相加。
NOTE:所有毗鄰的margin要一起參與運算愧膀,不能分步進行拦键。4、舉個例子:
1)用 浮動布局 顯示成兩行兩列 ——(為了解決浮動布局里的一個問題:元素浮動不換行怎么辦檩淋?)
<div id="A">
<div id="red" style="background: red;width: 100px;height: 100px;float: left;">
</div>
<div id="orange" style="background: orange;width: 100px;height: 100px;float: left;">
</div>
</div>
<div id="B">
<div id="yellow" style="background: yellow;width: 100px;height: 100px;float: left;">
</div>
<div id="green" style="background: green;width: 100px;height: 100px;float: left;">
</div>
</div>
我們可以看到四個盒子最終都處在一列里面芬为,為了達到我們的目的,可以**在其中一個外層盒子建立一個BFC**
<div id="A" style="display:inline-block;">
...
</div>
<div id="B">
...
</div>
- 實現多欄布局的一種方式
根據BFC布局規(guī)則第四條:
* BFC的區(qū)域不會與float box重疊蟀悦。(與浮動元素相鄰的已生成BFC的元素不能與浮動元素互相覆蓋)
利用該特性可以作為多欄布局的一種實現方式媚朦。
```
<div class="container">
<div class="column">column 1</div>
<div class="column">column 2</div>
<div class="column">column 3</div>
</div>
.column {
width: 31.33%;
background-color: green;
float: left;
margin: 0 1%;
}
.column:last-child
{
float: none;
overflow: hidden;
}
![多列布局.png](http://upload-images.jianshu.io/upload_images/3087126-a263255605a63fa0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
###六、關于BFC的總結
* BFC的幾個用途 (但是也有其他方法可以達到這種效果)
* 1日戈、BFC可以阻止垂直邊距疊加問題
* 2询张、BFC可以包含內部元素的浮動
* 3、BFC可以阻止元素被浮動覆蓋
* 4浙炼、BFC可以決定清除浮動的范圍
>參考文章:
[BFC(塊級格式化上下文)](http://www.reibang.com/p/66632298e355)
[我對BFC的理解](http://www.reibang.com/p/76484dff1cb5)
>其他文章推薦:
[理解CSS中的BFC](http://www.w3cplus.com/css/understanding-block-formatting-contexts-in-css.html)