在進行html佈局及css編寫的時候,你是否遇到過這樣的問題:
- 子元素設置浮動脫離文檔流後,父元素無法將其完全包裹
- 子元素浮動實現兩欄佈局時,另一個子元素與浮動子元素重疊
- 垂直方向的外邊距margin重疊
...
通常我們使用塊級格式化上下文(BFC)就能解決。
什麼是BFC?
塊格式化上下文(Block Formatting Context,BFC) 是Web頁面的可視化CSS渲染的一部分,是塊盒子的佈局過程發生的區域,也是浮動元素與其他元素交互的區域。
FC(formatting context)直譯過來是格式化上下文,它是頁面中的一塊渲染區域,有一套渲染規則,決定了其子元素如何佈局,以及和其他元素之間的關係和作用。
BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素,並且容器元素不會影響兄弟元素的佈局。
什麼情況下會創建BFC
- 根元素或包含根元素的元素
- 浮動元素(元素的 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(分別是HTML table、row、tbody、thead、tfoot的默認屬性)或 inline-table)
- overflow 值不爲 visible 的塊元素
- display 值爲 flow-root 的元素(新方式,文末會提及)
- contain 值爲 layout、content或 strict 的元素
- 彈性元素(display爲 flex 或 inline-flex元素的直接子元素)
- 網格元素(display爲 grid 或 inline-grid 元素的直接子元素)
- 多列容器(元素的 column-count 或 column-width 不爲 auto,包括 column-count 爲 1)
column-span 爲 all 的元素始終會創建一個新的BFC,即使該元素沒有包裹在一個多列容器中。
常見應用場景
使父元素包含浮動元素
下面例子解釋如何讓浮動內容和父元素等高,清楚浮動負面影響
html
<div class="outer">
<div class="float">I am a floated element.</div>
I am text inside the outer box.
</div>
css
.outer {
border: 5px dotted rgb(214,129,137);
border-radius: 5px;
width: 450px;
padding: 10px;
margin-bottom: 40px;
}
.float {
padding: 10px;
border: 5px solid rgba(214,129,137,.4);
border-radius: 5px;
background-color: rgba(233,78,119,.4);
color: #fff;
float: left;
width: 200px;
margin: 0 20px 0 0;
}
通過給左側文字設置向左浮動實現文字環繞效果是很常見的做法,當文本足夠長時,會看到如下效果,父元素可以完全包裹子元素。
但事實上,float中的文字已經脫離文檔,如果文檔流文字過少,浮動元素就會溢出父元素邊緣。
這時候爲父元素設置overflow: auto
或者除invisible
默認值之外的任何有效值都能創建BFC解決這個問題,使父元素包含浮動元素
.outer {
overflow: auto;
}
BFC防止垂直外邊距重疊
外邊距摺疊的規則是:當兩個塊級元素相鄰並且在同一個塊級格式化上下文時,它們垂直方向上的外邊距會產生重疊
html
<div class="outer">
<p>I am paragraph one and I have a margin top and bottom of 20px</p>
<p>I am paragraph two and I have a margin top and bottom of 20px</p>
</div>
css
.outer {
background-color: #ccc;
margin: 0 0 40px 0;
}
p {
padding: 0;
margin: 20px 0 20px 0;
background-color: rgb(233,78,119);
color: #fff;
}
由於p元素的邊緣和外部div上的邊距之間沒有內容,因此兩者將會合並,因此段落最終與框的頂部和底部齊平。我們在段落的上方和下方看不到任何灰色。如下圖:
當父元素設置了BFC之後,父元素與子元素p重疊區域將不再合併
.outer {
background-color: #ccc;
margin: 0 0 40px 0;
overflow: auto;
}
BFC防止文本環繞
依然像上面例子文字環繞效果的佈局和樣式
html
<div class="outer">
<div class="float">I am a floated element.</div>
<div class="text">I am text...</div>
</div>
css
.float{
float: left;
}
這時候如果不想要右側文字環繞浮動文字盒子,在左側div設置浮動的情況下,我可以通過使右邊div成爲BFC,使兩個兄弟div互相隔離、互不影響,從而達到去除文字環繞的效果。
.text {
overflow: auto;
}
創建BFC的新方式
創建BFC的許多方法通常會帶來一些副作用,目前爲止似乎最安全的就是overflow
屬性,但某些情況下我們不需要滾動條,此時滾動條就變成了這種方式的副作用,因此display
有個新的屬性flow-root
可以在任何需要創建BFC場景下使用,它並且不會帶來任何副作用。
flow-root
瀏覽器兼容情況:
瀏覽器對此值的支持是有限的,如果要在不支持flex或網格佈局瀏覽器創建回退,瞭解BFC阻止浮動元素的負面影響十分必要。
PS:更多前端資訊、技術乾貨,請關注公衆號「前端新視界」