BFC(Block Formatting Context),中文翻譯爲「塊格式化上下文」。它有一個明顯的特性,那就是若是一個元素擁有了 BFC 特性,那麼它內部元素不受外部元素的影響,外部元素也不會受其內部元素的影響。css
但到底什麼纔是 BFC 呢?html
先來看看 MDN 對 BFC 的解釋。瀏覽器
塊格式化上下文(Block Formatting Context,BFC) 是Web頁面的可視化CSS渲染的一部分,是佈局過程當中生成塊級盒子的區域,也是浮動元素與其餘元素的交互限定區域。ide
下列方式會建立塊格式化上下文:wordpress
- 根元素或包含根元素的元素
- 浮動元素(元素的 float 不是 none)
- 絕對定位元素(元素的 position 爲 absolute 或 fixed)
- 行內塊元素(元素的 display 爲 inline-block)
- 表格單元格(元素的 display爲 table-cell,HTML表格單元格默認爲該值)
- 表格標題(元素的 display 爲 table-caption,HTML表格標題默認爲該值)
- 匿名錶格單元格元素(元素的 display爲 table、table-row、 table-row-group、table-header-group、table-footer-group(分別是HTML table、row、tbody、thead、tfoot的默認屬性)或 inline-table)
- overflow 值不爲 visible 的塊元素
- display 值爲 flow-root 的元素
- contain 值爲 layout、content或 strict 的元素
- 彈性元素(display爲 flex 或 inline-flex元素的直接子元素)
- 網格元素(display爲 grid 或 inline-grid 元素的直接子元素)
- 多列容器(元素的 column-count 或 column-width 不爲 auto,包括 column-count 爲 1)
- column-span 爲 all 的元素始終會建立一個新的BFC,即便該元素沒有包裹在一個多列容器中(標準變動,Chrome bug)。
建立了塊格式化上下文的元素中的全部內容都會被包含到該BFC中。佈局
塊格式化上下文對浮動定位(參見 float)與清除浮動(參見 clear)都很重要。浮動定位和清除浮動時只會應用於同一個BFC內的元素。浮動不會影響其它BFC中元素的佈局,而清除浮動只能清除同一BFC中在它前面的元素的浮動。外邊距摺疊(Margin collapsing)也只會發生在屬於同一BFC的塊級元素之間。flex
感受怎麼樣?反正我讀下來的感受就是:ui
好像也沒具體的說什麼是 BFC 。spa
我的感受 BFC 就像女孩子的好感同樣,無法說清楚什麼纔算是女孩子對你有好感,可是一旦女孩子對你有好感,你就知道了。翻譯
BFC 同理,無法說清楚什麼是 BFC ,可是當 BFC 一出現,你就知道那個東西屬不屬於 BFC ,也就是擁有某些特定屬性的東西就是 BFC ,能觸發 BFC 的屬性 MDN 上都有說明。
BFC 元素裏面元素不能影響外面的元素,利用這個特性,能夠用來管住子元素。
咱們知道,當一個元素變成浮動元素後,那麼它就會脫離文檔流,對頁面佈局產生影響,利用 BFC 就可緊緊管住浮動元素,消除這種影響,
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>BFC</title>
</head>
<body>
<div class="father">
<div class="child"></div>
</div>
</body>
<style> .father { width: 300px; border: 1px solid red; } .child { width: 200px; height: 100px; background: pink; } </style>
</html>
複製代碼
從動態圖中能夠看到,當咱們給child
元素加一個浮動時,它就會脫離father
元素的掌控,若是這時候把father
元素變成 BFC (float: left;
、 display: inline-block;
均可以將元素變成 BFC 元素,其餘更多方法看 MDN 的解釋),那麼child
元素就會從新被father
元素所掌控。
對於清楚浮動,也能夠利用clearfix
來實現,這個更推薦clearfix
,由於 BFC 有反作用,除了display: flow-root
以外,其餘將元素變成 BFC 的都是給元素加了一個其餘的屬性,這就會形成反作用。
display: flow-root
是一個專門生成 BFC 的一個屬性,可是它是一個高級屬性,瀏覽器支持不全面。
當咱們給子元素一個margin
時,它的margin
部分會跑到父級元素外面去。
當給子元素加一個margin-top: 100px;
後,會發現子元素比父元素大了,這個時候把父級元素變成 BFC 後,父級元素又會從新把子元素包進來。
BFC 元素外面的元素不能影響其裏面的元素,利用這個特性能夠和兄弟元素劃清界限,不受兄弟元素的影響。
咱們知道,在CSS當中,相鄰的兩個盒子(多是兄弟關係也多是祖先關係)的外邊距能夠結合成一個單獨的外邊距。這種合併外邊距的方式被稱爲摺疊,而且於是所結合成的外邊距稱爲摺疊外邊距。
而當其中一個元素變成了 BFC 以後,裏面的子元素就不會與這個元素的相鄰元素髮生外邊距疊加。
來看例子。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>BFC</title>
</head>
<body>
<div class="child"></div>
<div class="father">
<div class="child"></div>
</div>
<div class="child"></div>
</body>
<style> .father{ } .child{ width: 200px; height: 100px; background: pink; margin: 20px; } </style>
</html>
複製代碼
這時候會發生外邊距疊加,它們中間的邊距爲20px
。若是存在 BFC ,就會與旁邊的元素劃清界限,也就不會發生外邊距疊加了。
從代碼及動態圖能夠看到,實際上是father
元素裏面的child
元素與father
元素的兄弟元素髮生了外邊距疊加,當father
元素變成 BFC 後,裏面的child
元素與father
元素的兄弟消除了外邊距疊加。
咱們來看另一種狀況,看下面的動態圖。
從圖中能夠看到,BFC 元素自己不會與其兄弟元素消除外邊距疊加,它只能消除其子元素與 BFC 兄弟元素之間的外邊距疊加。
咱們知道當兄弟元素變成浮動元素後,它就會「騎」在咱們身上,這咱們確定不能忍啊。那咋辦呢?把咱們本身變成 BFC 就行了。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>BFC</title>
</head>
<body>
<div class="father">
<div class="child1"></div>
<div class="child2"></div>
</div>
</body>
<style> .father{ width: 350px; background: #999; } .child1{ float: left; width: 100px; height: 200px; background: pink; } .child2{ display: flow-root; width: 200px; height: 300px; background: red; } </style>
</html>
複製代碼
那我想離這個想壓迫個人兄弟遠點那怎麼辦?咱們天然而然地想到了margin-left
,來試試margin-left: 20px;
,來看看效果。
咦?咋沒用呢?來看看它的margin
。
原來兄弟元素雖然不能壓迫咱們自身,但它仍舊能夠「騎」在咱們的外邊距上。正所謂 BFC 的一個特性:外部元素不能影響 BFC 內部元素,但沒說外部元素不能影響 BFC 元素自己。
既然這樣,那就加大力度,我來個margin-left: 120px
。
這下卻是與兄弟元素分開了,但有一個很大的缺點,當兄弟元素的寬度發生變化時,它們之間的間距也發生了變化,若是想要其間距固定怎麼辦?
咱們換個思路,把margin
寫在浮動元素上怎樣?
從動態圖中能夠看到,當margin
寫在浮動元素上後,無論其寬度怎麼變,與兄弟 BFC 元素總會有着固定的間隔。
利用這個特性,咱們能完成一個多欄的佈局。
文章中若有錯誤之處,忘不吝賜教。
參考資料: