BFC是耳熟能詳的一個東西了,常常聽到,其實在項目中也常常用到,好比最經常使用的清除浮動,自適應兩欄佈局等等。只是都沒有去深究其原理和相關的知識點,今天就一塊兒來好好學習一下吧。css
要明白BFC
是什麼,咱們要先來了解幾個相關的概念。html
MDN對其描述以下:前端
當對一個文檔進行佈局(lay out)的時候,瀏覽器的渲染引擎會根據標準之一的CSS基礎盒模型(CSS basic box model)
,將全部元素表示爲一個個矩形的盒子(box)。CSS決定這些盒子的大小、位置和以及屬性(例如顏色、背景、邊框尺寸...)。css3
每一個盒子由四個部分(或稱區域)組成,其效用由它們各自的邊界(Edge)所定義(原文:defined by their respective edges,可能意指容納、包含、限制等)。如圖,與盒子的四個組成區域相對應,每一個盒子有四個邊界:內容邊界 Content edge、內邊距邊界 Padding Edge、邊框邊界 Border Edge、外邊框邊界 Margin Edge。瀏覽器
咱們在瀏覽器的控制檯也能夠很清楚的看到頁面的每個元素(除了單獨的文本元素),其實都是一個盒子:安全
更加詳細的介紹能夠參考MDN或者W3C規範的描述:bash
MDN 對其描述以下:佈局
CSS視覺格式化模型(visual formatting model)是用來處理和在視覺媒體上顯示文檔時使用的計算規則。該模型是CSS的基礎概念之一。post
視覺格式化模型會根據CSS盒子模型
將文檔中的元素轉換爲一個個盒子,每一個盒子的佈局由如下因素決定:
關於不一樣類型盒子的介紹,你們能夠直接看MDN,寫的很詳細了,這裏就再也不闡述。這邊着重講下定位方案。
一旦生成了盒子,CSS引擎就須要定位它們以完成佈局。在定位的時候,瀏覽器會根據元素的盒類型和上下文對這些元素進行定位,能夠說盒就是定位的基本單位。定位時有三種定位方案,分別是:常規流(即普通流)、浮動流以及絕對定位。
position
爲static
或relative
,而且float
爲none
時,會觸發常規流position: static
,盒的位置是常規流佈局裏的位置;position: relative
,盒偏移位置右這些屬性定義:top
、bottom
、left
、right
。即便有偏移,仍然保留原有的位置,其餘常規流不能佔用這個位置。clear
屬性;top
、bottom
、left
、right
;position: absolute
,元素定位相對於最近的一個relative
、absolute
或fixed
的父元素,若是沒有則相對於body
Formatting context是W3C CSS2.1規範中的一個概念。它是頁面中一塊渲染區域,而且有一套渲染規則,它決定了其子元素將如何定位,以及和其餘元素的關係和相互做用。最多見的Formatting context有Block formatting context(簡稱BFC)和Inline formatting context(簡稱IFC)。
CSS2.1中只有BFC
和IFC
,CSS3中還增長了GFC
和FFC
。咱們主要來說下BFC
。
好了,接下來輪到咱們的主角BFC
出場了。
BFC
(Block Formatting Context)直譯爲塊級格式化上下文。它是一個獨立的渲染區域,只有Box-level box參與,它規定了內部的Block-level box如何佈局,而且與這個區域外部絕不相干。
講了這麼多概念,說下本身的理解,若是有不對的地方,煩請指出,感激涕零。
CSS的盒模型
將全部元素表示爲一個個盒子;視覺格式化模型
來定義的,盒子的類型能夠分爲:行內盒子(inline)、行內級盒子(inine level)、原子行內級盒子(atomic inine-level)、塊盒子(block);是否是能夠這樣理解:BFC
就是普通流中的元素佈局定位時的一個執行環境?
writing-mode
屬性。)margin
決定。屬於同一個BFC
的兩個相鄰Box的margin
會發生重疊BFC
的區域不會與float box重疊BFC
就是頁面上的一個隔離的獨立的容器,容器裏面的子元素不會影響到外面的元素,反之亦如此BFC
的高度時,浮動元素也參與計算float
屬性值不爲none
position
爲absolute
或fixed
display
爲inline-block
、table-cell
、table-caption
、flex
、inline-flex
overflow
不爲visible
其實還有不少,這裏列出的是一些比較經常使用的,跟詳細的能夠看MDN。
實現自適應兩欄佈局的方法有不少,可是我以爲BFC
的方式應該是最簡單的了。
<body>
<div class="container">
<div class="side"></div>
<div class="main"></div>
</div>
</body>
複製代碼
.container {
width: 400px;
}
.side {
float: left;
width: 100px;
height: 100px;
background: lightpink;
}
.main {
height: 300px;
background: lightblue;
}
複製代碼
頁面截圖:
根據BFC
佈局規則第3條:
每一個元素的margin box的左邊,與包含快border box的左邊相接觸(對於從左往右的格式化,不然相反),即便存在浮動也是如此(除非該盒創建了一個新的塊格式化上下文)
即便存在浮動元素side
,main
的左邊依然會與包含快的左邊相接觸。
根據BFC
佈局規則第4條:
BFC
的區域不會與float box重疊
因此,咱們能夠給main
建立一個新的BFC
,這樣就不會跟浮動的side
重疊了,它會根據包含塊的寬度和side
的寬度,自動變窄。
給main
加上overflow: hidden
main {
overflow: hidden;
}
複製代碼
再來看下效果:
<div class="parent">
<div class="child"></div>
</div>
複製代碼
.parent {
width: 200px;
border: 2px solid blue;
background: lightblue;
}
.child {
float: left;
width: 100px;
height: 100px;
border: 2px solid red;
background: lightcoral;
}
複製代碼
頁面截圖:
能夠看到,因爲子元素設置了浮動,而父元素又沒有設置高度,致使父元素高度塌陷了:沒有自動被子元素的高度撐開。
根據BFC
佈局規則第6條:
計算BFC的高度時,浮動元素也參與計算
咱們能夠給父元素parent
觸發BFC
,那麼它在計算高度時,內部的浮動元素也會參與計算。
.parent {
overflow: hidden;
}
複製代碼
再看下效果:
<div class="box">box</div>
<div class="box">box</div>
複製代碼
.box {
width: 200px;
height: 200px;
margin: 100px;
background: red;
}
複製代碼
頁面截圖:
根據BFC
佈局規則第2條:
Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊
能夠看到,第一個div的下邊距跟第二個的上邊距發生了重疊。
重疊的結果按照以下規則計算:
產生摺疊的必備條件:margin必須是鄰接的!
咱們只要給其中一個div外層再包裹一層div,而後觸發其生成一個新的BFC
,它們就不會發生重疊了。
<div class="box">box</div>
<div class="new-bfc">
<div class="box">box</div>
</div>
複製代碼
.new-bfc {
overflow: hidden;
}
複製代碼
頁面截圖:
還有不少其餘的例子,好比能夠避免文字環繞、多列布局等等,這裏就再也不一一列舉,你們有興趣的能夠本身多嘗試下,這裏有一個網址能夠在線演示,更加直觀, 連接地址:www.cnblogs.com/xiaohuochai…
咱們上面舉的例子都是經過overflow
來建立BFC
,可是其實這個方法會有兩個問題。
BFC
時可能會存在一些反作用。例如,使用overflow
建立BFC
後,在某些狀況下可能會看到出現一個滾動條或者元素內容被裁切。這是因爲overflow
屬性的設計是用來讓你告訴瀏覽器如何定義元素的溢出狀態的。瀏覽器執行了它最基本的定義。overflow
也可能會使另外一個開發人員感到困惑。他們可能會各類猜測:這裏爲何要把overflow
的值設爲auto
或hidden
?原來的開發人員這樣作的意義是什麼?原來的開發人員是想讓這裏出現滾動條嗎?因此實際項目開發中,還須要根據項目的需求來選擇合適的方法,最好也能在代碼裏寫明註釋。
那有沒有什麼更好的方式呢?CSS工做組定義了一個新的屬性值:display: flow-root
。
你可使用display: flow-root
安全的建立BFC
,來解決上文中提到的各類問題:自適應兩欄佈局、清除內部浮動、阻止margin重疊等等。
caniuse上display: flow-root
在各瀏覽器的兼容狀況,看圖:
目前來看,兼容性仍是差了一點。
有關於
flow-root
的詳細介紹能夠看這篇文章:www.w3cplus.com/css3/displa…
能夠想象一下,BFC
就至關於咱們現實中的一個紙箱(盒子),箱子裏面的東西的放置(佈局)是不會受到外部其餘東西的影響的,它造成了一個獨立的封閉的區域。固然它裏面東西的放置(佈局)也不會影響到外面的東西。
感謝您的閱讀,但願對你有所幫助,但願你能經過這篇文章能對BFC
有一個比較全面的理解並能實際應用到項目開發中。本人水平有限,若是文中有不當的地方煩請指正,感激涕零。
歡迎你們關注個人公衆號前端幫幫忙
,一塊兒交流學習,共同進步。
參考: