塊格式化上下文(Block Formatting Context,BFC
) 是Web
頁面的可視化CSS
渲染的一部分,是塊盒子的佈局過程發生的區域,也是浮動元素與其他元素交互的區域。
下列方式會創建塊格式化上下文:
- 根元素(
<html>
) - 浮動元素(元素的
float
不是none
) - 絕對定位元素(元素的
position
爲absolute
或fixed
) - 行內塊元素(元素的
display
爲inline-block
) - 表格單元格(元素的
display
爲table-cell
,HTML
表格單元格默認爲該值) - 表格標題(元素的
display
爲table-caption
,HTML
表格標題默認爲該值) - 匿名錶格單元格元素(元素的
display
爲table、table-row、table-row-group、table-header-group、table-footer-group
(分別是HTMLtable、row、tbody、thead、tfoot
的默認屬性)或inline-table
) overflow
值不爲visible
的塊元素display
值爲flow-root
的元素contain
值爲layout、content
或paint
的元素- 彈性元素(
display
爲flex
或inline-flex
元素的直接子元素) - 網格元素(
display
爲grid
或inline-grid
元素的直接子元素) - 多列容器(元素的
column-count
或column-width
不爲auto
,包括column-count
爲 1) column-span
爲all
的元素始終會創建一個新的BFC
,即使該元素沒有包裹在一個多列容器中。
塊格式化上下文包含創建它的元素內部的所有內容.
塊格式化上下文對浮動定位(參見 float
)與清除浮動(參見 clear
)都很重要。浮動定位和清除浮動時只會應用於同一個BFC
內的元素。浮動不會影響其它BFC
中元素的佈局,而清除浮動只能清除同一BFC
中在它前面的元素的浮動。外邊距摺疊(Margin collapsing
)也只會發生在屬於同一BFC
的塊級元素之間。
範例
讓浮動內容和周圍的內容等高
爲了更好的理解BFC
,我們先看看下面這些。
在下面的例子中,我們讓 <div>
元素浮動,並給它一個邊框效果。<div>
裏的內容現在已經在浮動元素周圍浮動起來了。由於浮動的元素比它旁邊的元素高,所以<div>
的邊框穿出了浮動。正如我們在這篇文章中 guide to in-flow and out of flow elements 解釋的,浮動脫離了文檔流,所以 <div>
的 background
和 border
僅僅包含了內容,不包含整個浮動。
.box {
background-color: rgb(224, 206, 247);
border: 5px solid rebeccapurple;
}
.float {
float: left;
width: 200px;
height: 150px;
background-color: white;
border:1px solid black;
padding: 10px;
}
<div class="box">
<div class="float">I am a floated box!</div>
<p>I am content inside the container.</p>
</div>
創建一個會包含這個浮動的BFC
,通常的做法是設置父元素 overflow: auto
或者設置其他的非默認的 overflow: visible
的值。
.box {
background-color: rgb(224, 206, 247);
border: 5px solid rebeccapurple;
overflow: auto;
}
.float {
float: left;
width: 200px;
height: 150px;
background-color: white;
border:1px solid black;
padding: 10px;
}
<div class="box">
<div class="float">I am a floated box!</div>
<p>I am content inside the container.</p>
</div>
設置 overflow: auto
創建一個新的BFC
來包含這個浮動。我們的 <div>
元素現在變成佈局中的迷你佈局。任何子元素都會被包含進去。
使用 overflow
來創建一個新的BFC
,是因爲 overflow
屬性告訴瀏覽器你想要怎樣處理溢出的內容。當你使用這個屬性只是爲了創建BFC
的時候,你可能會發現一些不想要的問題,比如滾動條或者一些剪切的陰影,需要注意。另外,對於後續的開發,可能不是很清楚當時爲什麼使用overflow
。所以你最好添加一些註釋來解釋爲什麼這樣做。
外邊距塌陷
創建新的BFC
避免兩個相鄰 <div> 之
間的 外邊距合併 問題
HTML
<div class="blue"></div>
<div class="red-outer">
<div class="red-inner">red inner</div>
</div>
CSS
.blue, .red-inner {
height: 50px;
margin: 10px 0;
}
.blue {
background: blue;
}
.red-outer {
overflow: hidden;
background: red;
}
結果
使用display: flow-root
一個新的 display
屬性的值,它可以創建無副作用的BFC
。在父級塊中使用 display: flow-root
可以創建新的BFC
。
.box {
background-color: rgb(224, 206, 247);
border: 5px solid rebeccapurple;
display: flow-root;
}
.float {
float: left;
width: 200px;
height: 150px;
background-color: white;
border:1px solid black;
padding: 10px;
}
<div class="box">
<div class="float">I am a floated box!</div>
<p>I am content inside the container.</p>
</div>
給 <div> display: flow-root
屬性後,<div>
中的所有內容都會參與BFC
,浮動的內容不會從底部溢出。
The value name of flow-root makes sense when you understand you are creating something that acts like the root element ( element in browser) in terms of how it creates a new context for the flow layout inside it.