面試官:談談你對 BFC 的理解?
一、是什麼
我們在頁面佈局的時候,經常出現以下情況:
-
這個元素高度怎麼沒了?
-
這兩欄佈局怎麼沒法自適應?
-
這兩個元素的間距怎麼有點奇怪的樣子?
-
......
歸根究底是元素之間相互的影響,導致了意料之外的情況,這裏就涉及到BFC
概念
BFC(Block Formatting Context),即塊級格式化上下文,它是頁面中的一塊渲染區域,並且有一套屬於自己的渲染規則:
-
內部的盒子會在垂直方向上一個接一個的放置
-
對於同一個 BFC 的倆個相鄰的盒子的 margin 會發生重疊,與方向無關。
-
每個元素的左外邊距與包含塊的左邊界相接觸(從左到右),即使浮動元素也是如此
-
BFC 的區域不會與 float 的元素區域重疊
-
計算 BFC 的高度時,浮動子元素也參與計算
-
BFC 就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素,反之亦然
BFC
目的是形成一個相對於外界完全獨立的空間,讓內部的子元素不會影響到外部的元素
二、觸發條件
觸發BFC
的條件包含不限於:
-
根元素,即 HTML 元素
-
浮動元素:float 值爲 left、right
-
overflow 值不爲 visible,爲 auto、scroll、hidden
-
display 的值爲 inline-block、inltable-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid
-
position 的值爲 absolute 或 fixed
三、應用場景
利用BFC
的特性,我們將BFC
應用在以下場景:
防止 margin 重疊(塌陷)
<style>
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align:center;
margin: 100px;
}
</style>
<body>
<p>Haha</p>
<p>Hehe</p>
</body>
頁面顯示如下:
兩個p
元素之間的距離爲100px
,發生了margin
重疊(塌陷),以最大的爲準,如果第一個 P 的margin
爲 80 的話,兩個 P 之間的距離還是 100,以最大的爲準。
前面講到,同一個BFC
的倆個相鄰的盒子的margin
會發生重疊
可以在p
外面包裹一層容器,並觸發這個容器生成一個BFC
,那麼兩個p
就不屬於同一個BFC
,則不會出現margin
重疊
<style>
.wrap {
overflow: hidden;// 新的BFC
}
p {
color: #f55;
background: #fcc;
width: 200px;
line-height: 100px;
text-align:center;
margin: 100px;
}
</style>
<body>
<p>Haha</p>
<div class="wrap">
<p>Hehe</p>
</div>
</body>
這時候,邊距則不會重疊:
清除內部浮動
<style>
.par {
border: 5px solid #fcc;
width: 300px;
}
.child {
border: 5px solid #f66;
width:100px;
height: 100px;
float: left;
}
</style>
<body>
<div class="par">
<div class="child"></div>
<div class="child"></div>
</div>
</body>
頁面顯示如下:
而BFC
在計算高度時,浮動元素也會參與,所以我們可以觸發.par
元素生活才能BFC
,則內部浮動元素計算高度時候也會計算
.par {
overflow: hidden;
}
實現效果如下:
自適應多欄佈局
這裏舉個兩欄的佈局
<style>
body {
width: 300px;
position: relative;
}
.aside {
width: 100px;
height: 150px;
float: left;
background: #f66;
}
.main {
height: 200px;
background: #fcc;
}
</style>
<body>
<div class="aside"></div>
<div class="main"></div>
</body>
效果圖如下:
前面講到,每個元素的左外邊距與包含塊的左邊界相接觸
因此,雖然.aslide
爲浮動元素,但是main
的左邊依然會與包含塊的左邊相接觸
而BFC
的區域不會與浮動盒子重疊
所以我們可以通過觸發main
生成BFC
,以此適應兩欄佈局
.main {
overflow: hidden;
}
這時候,新的BFC
不會與浮動的.aside
元素重疊。因此會根據包含塊的寬度,和.aside
的寬度,自動變窄
效果如下:
小結
可以看到上面幾個案例,都體現了BFC
實際就是頁面一個獨立的容器,裏面的子元素不影響外面的元素
參考文獻
-
https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Block_formatting_context
-
https://github.com/zuopf769/notebook/blob/master/fe/BFC%E5%8E%9F%E7%90%86%E5%89%96%E6%9E%90/README.md
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/4WC-1COpRL0scgPqD3I-Sg