細說CSS中的BFC

做者:滴滴公共前端團隊 - 邱蓮css

BFC是什麼?

BFC(Block Formatting Context)直譯爲「塊級格式化範圍」。html

是 W3C CSS 2.1 規範中的一個概念,它決定了元素如何對其內容進行定位,以及與其餘元素的關係和相互做用。當涉及到可視化佈局的時候,Block Formatting Context提供了一個環境,HTML元素在這個環境中按照必定規則進行佈局。一個環境中的元素不會影響到其它環境中的佈局。前端

好比浮動元素會造成 BFC,浮動元素內部子元素的主要受該浮動元素影響,兩個浮動元素之間是互不影響的。這裏有點相似一個 BFC 就是一個獨立的行政單位的意思。git

也能夠說 BFC 就是一個做用範圍。能夠把它理解成是一個獨立的容器,而且這個容器的裏box的佈局,與這個容器外的絕不相干。github

BFC 的特徵:

  • 內部的Box會在垂直方向,一個接一個地放置。api

  • Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊瀏覽器

  • 每一個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此。微信

  • BFC的區域不會與float box重疊。佈局

  • BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素。反之也如此。flex

  • 計算BFC的高度時,浮動元素也參與計算

BFC 的應用場景有哪些?如何觸發 BFC?

知足下列條件中至少一項,便可觸發 BFC:

  1. float 的值不爲none。

  2. position 的值不爲static或者relative。

  3. display的值爲 table-cell, table-caption, inline-block, flex, 或者 inline-flex中的其中一個。

  4. 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部分:

  1. html代碼中,middle部分首先要放在container的最前部分,而後是left,right 。
  2. 將三者都設置 float:left, position:relative
  3. middle設置 width:100% 佔滿一行 。
  4. 此時middle佔滿一行,因此要把left拉到middle所在行的最左邊,使用 margin-left:-100%
  5. 這時left拉回到middle所在行的最左邊,但會覆蓋middle內容的左端,要把middle內容拉出來,因此在外圍container加上 padding:0 200px
  6. middle內容拉出來了,但left也跟着出來了,因此要還原,就對left使用相對定位 left:-200px
  7. 同理,right要拉到middle所在行的最右邊,使用 margin-left:-200pxright:-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」或掃描下面的二維碼

相關文章
相關標籤/搜索