BFC:塊級格式化上下文
1.盒模型和格式化上下文
Box: CSS佈局的基本單位
Box 是 CSS 佈局的物件和基本單位, 直觀點來說,就是一個頁面是由很多個 Box 組成的。元素的型別和 display 屬性,決定了這個 Box 的型別。 不同型別的 Box, 會參與不同的 Formatting Context(一個決定如何渲染文件的容器),因此Box內的元素會以不同的方式渲染。讓我們看看有哪些盒子:
- block-level box:display 屬性為 block, list-item, table 的元素,會生成
block-level box。並且參與 block fomatting context; - inline-level box:display 屬性為 inline, inline-block, inline-table
的元素,會生成 inline-level box。並且參與 inline formatting context; - run-in box: css3 中才有, 這兒先不講了。
Formatting context
Formatting context 是 W3C CSS2.1 規範中的一個概念。它是頁面中的一塊渲染區域,並且有一套渲染規則,它決定了其子元素將如何定位,以及和其他元素的關係和相互作用。最常見的 Formatting context 有 Block fomatting context (簡稱BFC)和 Inline formatting context (簡稱IFC)。
CSS2.1 中只有 BFC 和 IFC, CSS3 中還增加了 GFC 和 FFC。
BFC 定義
BFC(Block formatting context)直譯為”塊級格式化上下文”。它是一個獨立的渲染區域,只有Block-level box參與, 它規定了內部的Block-level Box如何佈局,並且與這個區域外部毫不相干。
2.BFC的佈局特性
- BFC就是頁面上的一個隔離的獨立容器,容器裡面的子元素不會影響到外面的元素。反之也如此。
- 內部的塊級元素會在垂直方向,一個接一個地放置,依然保留塊級元素的流體特性
- Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊
- 每個塊級子元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。
- BFC的區域不會與float box重疊。(根據第1條可以推出,當BFC外部存在浮動時,它不應該影響BFC內部Box的佈局,BFC會通過變窄,而不與浮動有重疊)
- 計算BFC的高度時,浮動元素也參與計算
3.如何產生BFC
- 根元素
- 浮動元素(float屬性不為none)
- position為absolute或fixed的元素(不推薦在自適應佈局中使用)
- display為inline-block,table-cell, table-caption, flex, inline-flex,grid
- overflow不為visible的塊元素(一般設定為overflow:hidden)
4.BFC應用場景:兩列自適應佈局
左列不定寬或者定寬,右列自適應,兩列中間有間距,可以在區域性使用float+BFC:
首先考慮如果.right沒有指定overflow:hidden規則時的情況:
當right不建立BFC時,.left和.right都處於根元素.parent建立的BFC中,根據BFC佈局特性3:
每個塊級子元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。
那麼.left和.right都會靠在.parent的左邊border上,又因為.left使用了浮動,根據堆疊上下文規則,普通流後代塊元素會顯示在浮動塊元素的下面,因此.left塊元素顯示在.right塊元素的上面。為了讓.right和浮動.left分開,設定.right的overflow屬性為hidden觸發它的BFC特性:
BFC的區域不會與float box重疊。
那麼兩者就分成了兩列。為了產生間距,首先考慮的是margin,但是如果左邊不定寬不能設定.right的margin-left(同時注意如果設定值必須設定.left的寬度加上間距而不僅是間距,因為它仍舊是相對於容器邊緣進行設定的),可以設定float元素的margin-right或者是padding-right,如程式碼所示:
CSS:
.left{
float:left;
margin-right:20px;/*距離右邊塊級元素20px*/
width:100px;/*不定寬,可以不寫由內容決定*/
}
.right{
overflow: hidden; /*right變成BFC*/
}
HTML:
<div class="parent">
<div class="left">
left
</div>
<div class="right">
right
</div>
</div>
BFC的其他應用場景包括:
清除內部浮動(計算BFC的高度時,浮動元素也參與計算,當父元素包含浮動元素時,觸發父元素的BFC特性可以讓父元素高度由浮動元素參與計算)
防止垂直margin的重疊(Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊,那麼可以通過讓其中一個Box觸發BFC特性來避免margin重疊)
5.BFC佈局優點
- 自適應內容由於封閉,更健壯,容錯性強。比方說,內部clear:both不會與兄弟float產生矛盾。而純流體佈局,clear:both會讓後面內容無法和float元素在一個水平上,產生布局問題。
- 自適應內容自動填滿浮動剩餘區域,無需關心浮動元素寬度,可以整站大規模應用。而純流體佈局,需要大小不確定的margin/padding等值撐開合適間距,無法CSS元件化。