BFC深入理解

哈哈落葉發表於2018-03-31

一直都知道overflow可以清除浮動,但是卻不知道這背後的原理。查了眾多資料後才發現有BFC這麼個東西,寫這篇文章一是為了加深記憶,二是為了加深理解。

什麼是BFC?
BFC的全稱是Block Formatting Context 塊級格式化上下文。
一般情況下BFC只存在於根級元素,但有時我們在設定某些CSS屬性時也會產生BFC。但是前提是必須是塊級元素

以下屬性宣告會產生BFC:
1、float不為none
2、overflow不為visible
3、position不為static和relative
4、display為inline-block table-cell table-caption
5、flex、inline-flex佈局

BFC佈局規則
1、內部元素會垂直排列
2、垂直方向的間隔由margin決定,同一個BFC裡同級別的兩個元素之間的margin會產生坍塌
3、元素會靠在外層元素的左邊或者右邊,float同理
4、BFC不會與float重疊(absolute,fixed除外)
5、BFC計算高度時,float元素的高度也參與計算
6、BFC是隔離的,它裡面元素就算翻江倒海也不會影響外層,外層的各種變化也不會影響BFC。

BFC應用

解決margin坍塌

      <div>
         <div class="elementA" style="margin: 10px"></div>
         <div class="elementB" style="margin: 10px"></div>
      </div> 
      

elementA與elementB之間的實際margin為10px;
在elementB的外層新增一個div設定BFC屬性,此時elementA, elementB的間隔為20px,程式碼如下:

      <div>
         <div class="elementA" style="margin: 10px"></div>
         <div style="overflow:hidden">
           <div class="elementB" style="margin: 10px"></div>
         </div>
      </div>    

解決float覆蓋

 <div>
     <div class="elmentA" style="float:left;width:100px;height:100px;"></div>
     <div class="elementB" style="height:200px">123</div>
 </div>

以上程式碼中,elmentA會覆蓋到elementB上。
解決方案如下,給elementB新增一個BFC屬性elementB便會避開elementA:

 <div>
     <div class="elmentA" style="float:left;width:100px;height:100px;"></div>
     <div class="elementB" style="height:200px;overflow:hidden">123</div>
 </div>
 

計算內層float元素的高度。

 <div class="wrapper">
       <div style="float:left;height:100px"></div>
 </div>
 

上述程式碼中,wrapper是沒有高度的,雖然子元素設定了高度為100px,但是由於子元素是float所以父元素沒有高度。
解決方案如下,給wrapper新增一個BFC屬性,這時wrapper的高度就為子元素的高度:

<div class="wrapper" style="overflow:hidden">
       <div style="float:left;height:100px"></div>
 </div>

對overflow:hidden的額外說明

當設定了一個元素為樣式為:

 overflow:hidden
 height:auto

元素首先會計算出自己的高度才知道應該裁剪哪一部分,當生成BFC時會首先計算裡面元素的高度,當裡面有float元素時會計算float元素的高度,並把float元素的高度加到自身高度中。但如果高度有具體的值時,float高度超過時還是會被裁剪。

對position:absolute以及position:fixed的額外說明

在本文前面提到過 BFC的區域不會和float區域重疊,但是absolute和fixed佈局有例外。absolute和fixed會覆蓋到float元素上,因為absolute和fixed已經脫離文件流。