CSS中的BFC机制
1 什么是BFC
塊格式化上下文BFC(Block Formatting Context,BFC) 是Web頁面的可視CSS渲染的一部分,是塊盒子的布局過程發生的區域,也是浮動元素與其他元素交互的區域。以上內容摘自MDN,其實通俗來講BFC就是一個獨立的布局環境,BFC中的元素布局不受外部元素的影響,也不會影響到外部元素。
2 如何觸發BFC
其實在日常開發中經常會主動觸發BFC:
以上列出的都是常見的幾種,更多觸發BFC的方式可查閱文檔MDN-BFC。除了主動觸發BFC,其實每個HTML文檔中都會被動觸發BFC,因為其根元素html本身就會形成一個BFC,可以理解為頁面中的所有元素都存在與某個BFC環境下。
3 BFC的特性
3.1 BFC內部依然遵循元素定位規則
在CSS中,元素定位規則分為以下三種:
BFC內部依然遵循元素定位規則這句話很好理解,前面提到根元素html本身會形成一個BFC,所以其內部自然遵循元素定位規則。
3.2 BFC內部相鄰元素垂直外邊距合并
屬于同一個BFC的內部兩個相鄰的元素的垂直外邊距會發生合并,這個特性在li標簽下格外明顯,舉個例子:
<ul><li>JavaScript</li><li>Python</li><li>C++</li><li>Java</li><li>Golang</li> </ul> ul {width: 200px; }li {list-style: none;border: 3px solid pink;border-radius: 3px;margin: 10px 0px; /* 關鍵代碼:為li標簽設置了10px的上下外邊距 */text-align: center; }在CSS中為li標簽設置了上下10px的外邊距,理論上每個li標簽在垂直距離上應該相距20px,但結果卻是每個li標簽在垂直距離上只相距10px。
這就是發生了外邊距合并。
3.3 不同BFC的相鄰元素不會外邊距合并
要解決3.2節中的外邊距合并問題,可以將每個被合并的元素都放在一個單獨的BFC環境下,這樣就不會發生外邊距合并,修改代碼如下,將每個li標簽用一個div標簽包裹:
<ul><div><li>JavaScript</li></div><div><li>Python</li></div><div><li>C++</li></div><div><li>Java</li></div><div><li>Golang</li></div></ul>再讓每個div標簽觸發BFC機制,這里選用最為常用的overflow: hidden;方式:
ul div {overflow: hidden;}效果如下:
不難發現兩個li標簽的距離為20px,這樣就通過BFC機制解決了外邊距合并問題。
3.4 BFC中元素的margin-box的左邊與子元素的border-box左邊相接
該特性的完整描述為“每個元素的margin-box的左邊會與包含塊border-box的左邊相接觸(對于從左到右的格式化,否則相反),即使存在浮動也會如此。”這句話晦澀難懂,先來解釋一下什么叫margin-box什么叫border-box,這兩個詞都來源于盒模型:
本文中僅討論W3C標準盒子模型,可以發現一個盒子由內至外分別為content、padding、border、margin四個部分組成,而每一個部分對應著content-box、padding-box、border-box、margin-box。
3.4.1 浮動的元素
舉個例子:
<div class="box1"><div class="box2"></div> </div> .box1 {width: 500px;height: 500px;background-color: red;overflow: hidden; /* 觸發BFC */ } .box2 {width: 300px;height: 300px;background-color: blue;float: left; /* 添加左浮動 */ }效果如下:
圖中box1、box2只設置了width、height,未設置margin、border、padding,此時參照的是父元素的最外層margin-box,所以box2與box1直接相接。但當父元素擁有padding或border時,此時參照的是padding-box或border-box,如下圖是設置了border的效果:
如下圖是給box1設置了padding的效果:
如下圖是給box1即設置了border也設置了padding的效果:
3.4.2 定位的元素
依然采用3.4.1節中的例子,將box2從左浮動改為絕對定位position: absolute;并設置left: 0;、top: 0;:
.box1 {width: 500px;height: 500px;background-color: red;overflow: hidden; /* 觸發BFC */border: 30px solid pink;padding: 30px;position: relative; } .box2 {width: 300px;height: 300px;background-color: blue;position: absolute;left: 0;top: 0; }在box1不設置margin、border、padding的情況下如下所示,其結果與浮動的元素相同:
給box1設置border后效果如下所示,其結果也與浮動的元素相同:
給box1設置padding后的效果如下所示,此時效果就與浮動的元素不同了,定位的元素會直接“忽視”padding的存在,直接box1的左邊緣相接:
給box1即設置border又設置padding的效果如下,可以發現box1的padding依然被“忽視”了,直接與border-box相接:
3.4.3 總結
- BFC內元素為浮動的情況下:參照的是content-box。
- BFC內元素為定位的情況下:參照的是padding-box。
3.5 BFC計算高度時包括浮動元素
該特性是用于清除浮動的方法之一,給父元素添加overflow: hidden屬性觸發BFC機制即可,詳細請閱讀CSS浮動和清除浮動中的4.3節。
3.6 BFC的區域不會與浮動元素發生重疊
該特性常用于兩欄自適應布局,即左邊固定寬度,右邊寬度自適應,如下圖所示:
實現方式如下:
4 BFC的應用場景
4.1 清除浮動
見3.5節
4.2 兩欄自適應布局
見3.6節
4.3 消除邊距合并
見3.3節
總結
以上是生活随笔為你收集整理的CSS中的BFC机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS浮动和清除浮动
- 下一篇: CSS层叠上下文、层叠顺序和层叠等级