作者:滴滴公共前端團隊 - 邱蓮
BFC是什麼?
BFC(Block Formatting Context)直譯為“塊級格式化範圍”。
是 W3C CSS 2.1 規範中的一個概念,它決定了元素如何對其內容進行定位,以及與其他元素的關係和相互作用。當涉及到視覺化佈局的時候,Block Formatting Context提供了一個環境,HTML元素在這個環境中按照一定規則進行佈局。一個環境中的元素不會影響到其它環境中的佈局。
比如浮動元素會形成 BFC,浮動元素內部子元素的主要受該浮動元素影響,兩個浮動元素之間是互不影響的。這裡有點類似一個 BFC 就是一個獨立的行政單位的意思。
也可以說 BFC 就是一個作用範圍。可以把它理解成是一個獨立的容器,並且這個容器的裡box的佈局,與這個容器外的毫不相干。
BFC 的特徵:
內部的Box會在垂直方向,一個接一個地放置。
Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊
每個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。
BFC的區域不會與float box重疊。
BFC就是頁面上的一個隔離的獨立容器,容器裡面的子元素不會影響到外面的元素。反之也如此。
計算BFC的高度時,浮動元素也參與計算
BFC 的應用場景有哪些?如何觸發 BFC?
滿足下列條件中至少一項,即可觸發 BFC:
float 的值不為none。
position 的值不為static或者relative。
display的值為 table-cell, table-caption, inline-block, flex, 或者 inline-flex中的其中一個。
overflow的值不為visible。
BFC 的應用場景:
1.解決 margin
疊加問題:
<div class="first-block"></div>
<div class="second-block">
<h2>DDFE</h2>
</div>複製程式碼
.first-block {
background: #F44336;
width: 200px;
height: 200px;
}
.second-block {
background: #00BCD4;
width: 200px;
height: 200px;
}複製程式碼
很簡單是吧,瀏覽器中的效果是這樣的:
為什麼 first-block 和 second-block 之間會有這麼寬的間距?
原因是:外邊距摺疊,這個間距是 h2 的上外邊距引起的。
CSS 裡面關於摺疊的條件:
兩個塊元素要產生摺疊現象,必須滿足一個必備條件:這兩個元素的 margin 必須是 相鄰 的;那麼如果定義相鄰呢,w3c 規範,兩個 margin 是鄰接的必須滿足以下條件:
必須是處於常規文件流(非float和絕對定位)的塊級盒子,並且處於同一個 BFC 當中。
沒有inline盒子,沒有空隙,沒有 padding 和 border 將他們分隔開。
都屬於垂直方向上相鄰的外邊距,可以是下面任意一種情況:
那麼我們就可以通過給元素叫邊框或者邊距來解決啦,我是不是狠聰明呢?
解決辦法 1:
摺疊問題解決了,但是由於有1px的邊框,second-block 看起來會比 first-block 寬一點,沒關係,新增 box-sizing: border-box
屬性可以解決這個問題:再加一句:box-sizing:border-box
;
解決辦法 2:
通過把 overflow 把 second-block 元素形成一個 BFC,完美解決!
2.用於佈局
杯佈局和雙飛翼佈局,他們的都要求三列布局,中間寬度自適應,兩邊定寬,這樣做的優勢是重要的東西放在文件流前面可以優先渲染。
樣子,就長這樣:
老規矩先貼上程式碼:
html部分:
css部分:
- html程式碼中,middle部分首先要放在container的最前部分,然後是left,right 。
- 將三者都設定
float:left
,position:relative
。 - middle設定
width:100%
佔滿一行 。 - 此時middle佔滿一行,所以要把left拉到middle所在行的最左邊,使用
margin-left:-100%
。 - 這時left拉回到middle所在行的最左邊,但會覆蓋middle內容的左端,要把middle內容拉出來,所以在外圍container加上
padding:0 200px
。 - middle內容拉出來了,但left也跟著出來了,所以要還原,就對left使用相對定位
left:-200px
。 - 同理,right要拉到middle所在行的最右邊,使用
margin-left:-200px
,right:-200px
。
其實除了聖盃佈局還有一個雙飛翼佈局,雙飛翼佈局是對聖盃佈局的一種改良,多一個div就可以不用相對佈局了,只用到了浮動和負邊距。
DOM結構:container內層增加了一個div
樣式:去掉了左右欄的相對定位,去掉包裹層padding,以中間欄新增div的margin代替。
是不是很簡單?
3.用於清除浮動,計算BFC高度
舉個例子:
我們想象中應該是這樣的:
但實際是卻是這樣的:
div 標籤沒有包住 ul 標籤,原因很簡單:container 下的子元素浮動了,因此div的高度就塌陷了。
要解決塌陷,就得清除浮動。
清除浮動就兩種方式:
1)利用 clear
屬性清除浮動。
2)使父容器形成 BFC。
給父元素 .container
加一句 overflow:hidden
觸發 bfc。
歡迎關注DDFE
GITHUB:github.com/DDFE
微信公眾號:微信搜尋公眾號“DDFE”或掃描下面的二維碼