什麼是 BFC
BFC 稱為塊級格式化上下文
它會建立一個特殊的區域,在這個區域中隻有 block box 參與布局,而BFC的一套規則就規定了在這個特殊的區域中如何進行布局,如何進行定位,區域内元素的互相關系和互相作用,這個特殊的區域不受外界影響。
block box 是指 display 屬性為 block、list-item、table 的元素,相應的還有 inline box, 如 display 屬性為 inline、inline-block、inline-table 的元素。
如何形成 BFC
那麼什麼樣的情況會建立一個 BFC 呢?MDN 總結如下:
- 根元素或其他包含它的元素
- 浮動元素(元素的 float 不是 none)
- 絕對定位元素(元素具有 position 為 absolute 或 fixed)
- 内聯塊(元素具有 display: inline - block)
- 表格單元格(元素具有 display: table - cell,HTML 表格單元格預設屬性)
- 表格标題(元素具有 display: table - caption, HTML 表格标題預設屬性)
- 具有 overflow 且值不是 visible 的塊元素
- display: flow - root 的元素
- column - span: all 的元素
BFC 決定了什麼
BFC 有自己的一套規則,包括:
- 内部的 box 将會獨占寬度,且在垂直方向,一個接一個排列
- box 垂直方向的間距由 margin 屬性決定,但是同一個 BFC 的兩個相鄰 box 的 margin 會出現邊距折疊現象
- 每個 box 水準方向上左邊緣,與 BFC 左邊緣相對齊,即使存在浮動也是如此
- BFC 區域不會與浮動元素重疊,而是會依次排列
- BFC 區域内是一個獨立的渲染容器,容器内元素和 BFC 區域外元素不會形成任何幹擾
- 浮動元素的高度也參與到 BFC 高度的計算當中
從上述規則中總結出最關鍵的三點:邊距折疊、清除浮動、自适應多欄布局。
BFC 實戰應用
例題1:
<style>
body {
width: 600px;
position: relative;
}
.left {
width: 80px;
height: 150px;
float: left;
background: blue;
}
.right {
height: 200px;
background: red;
}
</style>
<div class="left"></div>
<div class="right"></div>
效果如下
如何在不修改已有樣式情況下,加入新樣式,實作自适應兩欄布局。(.left 寬度固定,.right 占滿剩下寬度)
根據 BFC 布局規則:“每個 box 水準方向上左邊緣,與 BFC 左邊緣相對齊。即使存在浮動也是如此”,是以 .left 和 .right 的左邊相接觸。
是以就會出現 .right(普通box) 與 .left(BFC) 左邊緣對其,即使 .left 是浮動的。
BFC 布局規則還有這樣一條: BFC 區域不會與浮動元素重疊,而是會依次排列。
那麼就可以使 .right 形成 BFC,在 .right 中添加 overflow: hidden; 形成 BFC。
<style>
.right {
height: 200px;
background: red;
overflow: hidden;
}
</style>
例題2:
<style>
.root {
border: 5px solid green;
width: 300px;
}
.child {
border: 5px solid orange;
width: 100px;
height: 100px;
float: left;
}
</style>
<div class="root">
<div class="child child1"></div>
<div class="child child2"></div>
</div>
效果如下
因為 .child 為浮動元素,是以造成了“高度塌陷”現象,.root 的高度為 0。
那麼如何解決“高度塌陷”問題呢?
BFC 規則中:浮動元素的高度也參與到 BFC 高度的計算當中,那麼也就是說讓 .root 形成 BFC,其中的浮動元素 .child 的高度也會參與到 .root 的高度計算中,為 .root 添加樣式 overflow: hidden;
<style>
.root {
border: 5px solid green;
width: 300px;
overflow: hidden;
}
</style>
例題3:
<style>
p {
color: green;
background: orange;
width: 400px;
line-height: 100px;
text-align: center;
margin: 40px;
}
</style>
<p>p 1</p>
<p>p 2</p>
效果如下
常理來講 兩個 p 标簽的間距應該為80px,那實際效果為何是40px?
BFC 規則有一條:box 垂直方向的間距由 margin 屬性決定,但是同一個 BFC 的兩個相鄰 box 的 margin 會出現邊距折疊現象。
兩個 p 标簽屬于同一個 BFC ,是以兩個 p 的 margin 就出現了邊距折疊問題。
最簡單的解決辦法,我們可以在其中一個 p 标簽外再包裹一個元素,并讓這個外層元素形成 BFC ,那這兩個 p 标簽不再屬于同一個 BFC,解決了邊距重疊問題。
代碼如下:
<style>
p {
color: green;
background: orange;
width: 400px;
line-height: 100px;
text-align: center;
margin: 40px;
}
.wrapper {
overflow: hidden;
}
</style>
<p>p 1</p>
<div class="wrapper">
<p>p 2</p>
</div>
完結
BFC 可以解決 css 中很多經典的問題,如邊距折疊、多欄自适應、高度塌陷等問題。