BFC 為何物
格式化上下文(Block Formatting Context),是 Web 頁面中盒模型佈局的 CSS 渲染模式,主要指一個獨立的渲染區域或一個隔離的獨立容器。
需要什麼條件(即如何脫離文件流)
- 根元素(HTML元素),最大的一個BFC;
- 浮動元素,
float
除none
以外的值; - 定位元素,
position: [absolute | fixed]
; display: [inline-block | table-cell | table-caption]
;overflow: [hidden | auto | scroll]
, 即除visible
以外的值;
看例子
BFC 中的盒子對齊垂直存放
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>BFC 對齊</title>
<style>
* { margin: 0; padding: 0; }
.absolute { position: absolute; }
.left { float: left; }
.section { width: 520px; }
.section1 { background-color: red; min-height: 40px; }
.section2 { background-color: orange; min-height: 40px; }
.section3 { background-color: yellow; width: 100px; min-height: 40px; }
.section4 { background-color: green; min-height: 60px; }
</style>
</head>
<body>
<div class="section">
<div class="section1">section1</div>
<div class="section2">section2</div>
<div class="section3 left">section3 float</div>
<div class="section4">section4</div>
</div>
</body>
</html>
複製程式碼
哪怕浮動元素(section3)也接著上一個盒子垂直排列(所有的盒子都左對齊)。
外邊距摺疊
例子1 |
例子2 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>BFC margin</title>
<style>
* { margin: 0; padding: 0; }
.hidden { overflow: hidden; }
.section { margin: 20px auto; border:1px solid red; width: 800px; }
.section1 { background-color: orange; margin: 10px; min-height: 40px; }
.section2 { background-color: green; margin: 30px; min-height: 60px; }
</style>
</head>
<body>
<div class="section">
<div class="section1"></div>
<div class="section2"></div>
</div>
<div class="section">
<div class="hidden">
<div class="section1"></div>
</div>
<div class="section2"></div>
</div>
</body>
</html>
複製程式碼
例子1:兩個內部盒子 section1
和 section2
的垂直距離為 30px
而不是 40px
,因為垂直外邊距會摺疊,間距以較大的為準;
例子2:如何解決垂直外邊距不折疊呢?其實只要讓 BFC 容器裡的元素不會影響外面元素,同樣外面元素不影響 BFC 容器裡的元素,即讓 section1
或 section2
中一個盒子處於一個 BFC 容器中就行了;
不被浮動元素覆蓋
例子1 |
例子2 和 例子3 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>BFC float</title>
<style>
* { margin: 0; padding: 0; }
.hidden{ overflow: auto;}
.left { float: left; }
.right { float: right; }
.section { margin: 20px auto; border: 1px solid red; width: 800px; }
.section1 { background-color: orange; width: 100px; min-height: 40px; margin-right: 10px; }
.section2 { min-height: 60px; background-color: green;}
.section3 { background-color: pink; width: 100px; min-height: 40px; margin-left: 10px; }
</style>
</head>
<body>
<div class="section">
<div class="section1 left">
<p>section1</p>
<p>section1</p>
</div>
<div class="section2">
<p>section2</p>
<p>section2</p>
<p>section2</p>
<p>section2</p>
</div>
</div>
<div class="section">
<div class="section1 left">
<p>section1</p>
<p>section1</p>
</div>
<div class="section2 hidden">
<p>section2</p>
<p>section2</p>
<p>section2</p>
<p>section2</p>
</div>
</div>
<div class="section">
<div class="section1 left">
<p>section1</p>
<p>section1</p>
</div>
<div class="section3 right">
<p>section3</p>
<p>section3</p>
</div>
<div class="section2 hidden">
<p>section2</p>
<p>section2</p>
<p>section2</p>
<p>section2</p>
</div>
</div>
</body>
</html>
複製程式碼
- 例子1:字型環繞,浮動的盒子會遮蓋下面的盒子,但是下面盒子裡的文字是不會被遮蓋的,文字反而還會環繞浮動的盒子(挺有有趣的),如何阻止文字環繞,可看例子2;
- 例子2:兩欄佈局,左邊固定寬度,右邊不設寬(寬度自適應,隨瀏覽器視窗大小的變化而變化);
- 例子3:三欄佈局,左右兩邊固定寬度,中間不設寬(寬度自適應,隨瀏覽器的大小變化而變化);
BFC 包含浮動的塊
其實就是清浮動(利用 overflow:hidden
),可看面試之道之 CSS 佈局
最後
總結下特徵(能解決哪些問題)
- 內部的 box 在垂直方向存放;
- 垂直方向上的距離由
margin
決定(外間距之和); - BFC 的區域不會與
float
元素區域重疊(阻止文字環繞和實現多欄佈局); - 計算 BFC 的高度時,浮動元素也參與計算(清浮動);
- bfc 是頁面上的一個獨立容器,容器裡的子元素不會影響外面元素;