一、是什么
我們在頁面布局的時候,經常出現以下情況:
- 這個元素高度怎么沒了?
- 這兩欄布局怎么沒法自適應?
- 這兩個元素的間距怎么有點奇怪的樣子?
- ......
原因是元素之間相互的影響,導致了意料之外的情況,這里就涉及到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
實際就是頁面一個獨立的容器,里面的子元素不影響外面的元素