BFC 初體驗

1 引言

BFC(Block Formatting Context),中文翻譯爲「塊格式化上下文」。它有一個明顯的特性,那就是若是一個元素擁有了 BFC 特性,那麼它內部元素不受外部元素的影響,外部元素也不會受其內部元素的影響。css

但到底什麼纔是 BFC 呢?html

先來看看 MDN 對 BFC 的解釋。瀏覽器

2 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

3 BFC 的我的理解

我的感受 BFC 就像女孩子的好感同樣,無法說清楚什麼纔算是女孩子對你有好感,可是一旦女孩子對你有好感,你就知道了。翻譯

BFC 同理,無法說清楚什麼是 BFC ,可是當 BFC 一出現,你就知道那個東西屬不屬於 BFC ,也就是擁有某些特定屬性的東西就是 BFC ,能觸發 BFC 的屬性 MDN 上都有說明。

4 BFC 的用處

4.1 管住子元素

BFC 元素裏面元素不能影響外面的元素,利用這個特性,能夠用來管住子元素。

4.1.1 浮動元素

咱們知道,當一個元素變成浮動元素後,那麼它就會脫離文檔流,對頁面佈局產生影響,利用 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 的一個屬性,可是它是一個高級屬性,瀏覽器支持不全面。

4.1.2 margin

當咱們給子元素一個margin時,它的margin部分會跑到父級元素外面去。

當給子元素加一個margin-top: 100px;後,會發現子元素比父元素大了,這個時候把父級元素變成 BFC 後,父級元素又會從新把子元素包進來。

4.2 和兄弟劃清界限

BFC 元素外面的元素不能影響其裏面的元素,利用這個特性能夠和兄弟元素劃清界限,不受兄弟元素的影響。

4.2.1 清除外邊距疊加

咱們知道,在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 兄弟元素之間的外邊距疊加。

4.2.2 打破兄弟浮動元素的壓迫

咱們知道當兄弟元素變成浮動元素後,它就會「騎」在咱們身上,這咱們確定不能忍啊。那咋辦呢?把咱們本身變成 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 元素總會有着固定的間隔。

利用這個特性,咱們能完成一個多欄的佈局。

文章中若有錯誤之處,忘不吝賜教。

參考資料:

相關文章
相關標籤/搜索