一、BFC是什么
塊格式化上下文(Block Formatting Context,BFC) 是Web頁面的可視CSS渲染的一部分,是塊盒子的布局過程發生的區域,也是浮動元素與其他元素交互的區域。
官方的定義比較高深莫測,我還是更喜歡《CSS世界》這本書對BFC的解釋,我們可以將BFC想象成一個“結界”,結界的意思大家應該都很清楚吧,一旦把某個元素設為BFC,那這個元素內部和外部就互不干涉,相當於把這個元素內部變成了一個封閉空間,不管內部怎么變化都影響不到外面,外面也影響不到里面。這有什么好處呢?我們在進行布局的時候,可以不用考慮其他元素的影響,比如margin重疊和浮動等,也可以防止BFC內部元素到處亂跑。
二、BFC特點
- 一個元素具有BFC,那么它內部子元素的變化不會影響外部元素的布局。
- BFC元素不會與其他元素發生margin重疊,但屬於同一個BFC的兩個相鄰容器的上下margin會重疊。
- BFC可以清除浮動,但計算高度的時候要將浮動元素考慮進去。
- BFC內的容器在垂直方向依次排列。
- BFC不會與浮動元素發生重疊。
- 可實現更健壯、更智能的自適應布局。
三、BFC觸發條件
- <html>根元素;
- float的值不為none;
- overflow的值為auto、scroll或hidden;
- display的值為table-cell、table-caption和inline-block中的任何一個;
- position的值不為relative和static。
在網上找了個圖,出處在這篇文章 ,方便理解。
四、案例
(1)清除浮動

1 .father { 2 margin-top: 100px; 3 width: 400px; 4 /* overflow: hidden; */ 5 border: 5px solid grey; 6 background-color: pink; 7 } 8 9 .son { 10 11 height: 100px; 12 width: 100px; 13 float: left; 14 background-color: yellow; 15 border: 1px solid grey; 16 } 17 <div class="father"> 18 <div class="son"></div> 19 <div class="son"></div> 20 </div>
父元素不設置高度時,子元素浮動脫離文檔流,導致父元素高度坍塌。
如下圖所示:
給父元素添加BFC,父元素的高度需要計算浮動的元素高度,達到了清除浮動的目的,且不影響外部布局。如下圖所示
(2)阻止margin重疊

1 <style> 2 * { 3 margin: 0; 4 padding: 0; 5 } 6 7 .bro1, 8 .bro2 { 9 margin: 30px; 10 width: 100px; 11 height: 100px; 12 background-color: pink; 13 border: 1px solid grey; 14 } 15 </style> 16 17 <body> 18 <div class="bro1"></div> 19 <div class="bro2"></div> 20 21 22 </body>
相鄰兄弟元素處於同一個BFC區域所以會發生縱向重疊,效果如下:
給其中一個兄弟元素添加BFC,使兩者處於不同的BFC區域互不影響,代碼如下:

1 <style> 2 * { 3 margin: 0; 4 padding: 0; 5 } 6 7 .bfc { 8 overflow: hidden; 9 } 10 11 .bro1, 12 .bro2 { 13 margin: 30px; 14 width: 100px; 15 height: 100px; 16 background-color: pink; 17 border: 1px solid grey; 18 } 19 </style> 20 21 <body> 22 <div class="bfc"> 23 <div class="bro1"></div> 24 </div> 25 26 <div class="bro2"></div> 27 </body>
(3)自適應布局
BFC的結界特性最重要的用途其實不是去margin重疊或者是清除浮動,而是實現更健壯、更智能的自適應布局,我們用文字環繞舉個例子,代碼如下:

1 <style> 2 .left { 3 float: left; 4 height: 100px; 5 width: 300px; 6 background-color: yellow; 7 border: 1px solid grey; 8 } 9 10 .father { 11 height: 500px; 12 width: 500px; 13 background-color: pink; 14 border: 1px solid grey; 15 } 16 17 </style> 18 19 <body> 20 <div class="father"> 21 <div class="left">我是浮動的</div> 22 <p> 23 我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字 24 </p> 25 26 </div> 27 </body>
效果圖:
從效果圖可以看到文字因為受到浮動元素的影響而被環繞了,如果此時給它添加BFC特性的屬性,則根據BFC的表現原則,具有BFC特性的元素的子元素不會受到外部元素的影響,也不會影響外部元素,於是這里的文字為了不和浮動元素產生任何交集,會順着浮動邊緣形成自己的封閉上下文,如下圖所示(紅線為浮動邊緣):

1 <style> 2 .left { 3 float: left; 4 height: 100px; 5 width: 300px; 6 background-color: yellow; 7 border: 1px solid grey; 8 } 9 10 .father { 11 height: 500px; 12 width: 500px; 13 background-color: pink; 14 border: 1px solid grey; 15 } 16 17 /* 給文字添加bfc屬性 */ 18 .bfc { 19 overflow: hidden; 20 } 21 </style> 22 23 <body> 24 <div class="father"> 25 <div class="left">我是浮動的</div> 26 <p class="bfc"> 27 我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字我是環繞的文字 28 </p> 29 30 </div> 31 </body>
效果圖:
也就是說,普通流體元素在設置了overflow:hidden后,會自動填滿容器中除了浮動元素以外的空間,形成自適應布局效果,而且這種自適應布局要比純流體自適應更加智能。比方說,我們讓浮動元素的尺寸變大或者變小,右側自適應內容無須更改任何樣式代碼,都可以自動填滿剩余的空間。例如,我們將浮動元素的寬度從300px改為100px,結果如下所示:
總的來說,和基於純流體特性實現的兩欄或多欄自適應布局相比,基於BFC特性的自適應布局有如下優點。
- 自適應內容由於封閉而更加健壯,容錯性更強。比方說,內部設置clear:both不會與float元素相互干擾而導致錯位。
- 自適應內容自動填滿浮動以外區域,無須關心浮動元素寬度,可以整站大規模應用。
看上去BFC很超能,但是由於絕大多數的觸發BFC的屬性自身都有一些古怪的特性,所以,能兼容流體特性和BFC特性來實現無敵自適應布局的屬性並不多,還是得根據實際情況進行選擇,反正哪種好用就用哪種吧。