什麼是BFC?

前言

對於BFC的概念以及應用場景一直都不是很明白,今天着重去了解了一下,作了如下總結。css

BFC的定義

在解釋 BFC 是什麼以前,須要先介紹 Box、Formatting Context的概念。css3

Box: CSS佈局的基本單位

  Box 是 CSS 佈局的對象和基本單位, 直觀點來講,就是一個頁面是由不少個 Box 組成的。元素的類型和 display 屬性,決定了這個 Box 的類型。 不一樣類型的 Box, 會參與不一樣的 Formatting Context(一個決定如何渲染文檔的容器),所以Box內的元素會以不一樣的方式渲染。讓咱們看看有哪些盒子: block-level box:display 屬性爲 block, list-item, table 的元素,會生成 block-level box。而且參與 block fomatting context; inline-level box:display 屬性爲 inline, inline-block, inline-table 的元素,會生成 inline-level box。而且參與 inline formatting context; run-in box: css3 中才有, 這兒先不講了。git

Formatting context

  Formatting context 是 W3C CSS2.1 規範中的一個概念。它是頁面中的一塊渲染區域,而且有一套渲染規則,它決定了其子元素將如何定位,以及和其餘元素的關係和相互做用。最多見的 Formatting context 有 Block fomatting context (簡稱BFC)和 Inline formatting context (簡稱IFC)。 CSS2.1 中只有 BFC 和 IFC, CSS3 中還增長了 GFC 和 FFC。bash

BFC

  BFC(Block Formatting Context)直譯爲「塊級格式化範圍」。是 W3C CSS 2.1 規範中的一個概念,它決定了元素如何對其內容進行定位,以及與其餘元素的關係和相互做用 當涉及到可視化佈局的時候,Block Formatting Context提供了一個環境,HTML元素在這個環境中按照必定規則進行佈局。一個環境中的元素不會影響到其它環境中的佈局。好比浮動元素會造成BFC,浮動元素內部子元素的主要受該浮動元素影響,兩個浮動元素之間是互不影響的。這裏有點相似一個BFC就是一個獨立的行政單位的意思。 也能夠說BFC就是一個做用範圍。能夠把它理解成是一個獨立的容器,而且這個容器的裏box的佈局,與這個容器外的絕不相干ide

怎樣才能造成BFC

  1. float的值不能爲none
  2. overflow的值不能爲visible
  3. display的值爲table-cell, table-caption, inline-block中的任何一個
  4. position的值不爲relative和static 

BFC的約束規則

  1. 內部的Box會在垂直方向上一個接一個的放置
  2. 垂直方向的距離有margin決定(屬於同一個BFC的兩個相鄰Box的margin會發生重疊,與方向無關)
  3. 每一個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此
  4. BFC的區域不會與float的元素區域重疊
  5. 計算BFC的高度時,浮動子元素也參與計算
  6. BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面元素,反之亦然

看到以上的幾條約束,讓我想起學習css時的幾條規則佈局

Block元素會擴展到與父元素同寬,因此block元素會垂直排列 垂直方向上的兩個相鄰DIV的margin會重疊,而水平方向不會(此規則並不徹底正確) 浮動元素會盡可能接近往左上方(或右上方) 爲父元素設置overflow:hidden或浮動父元素,則會包含浮動元素學習

BFC的做用

1. 不和浮動元素重疊

若是一個浮動元素後面跟着一個非浮動的元素,那麼就會產生一個覆蓋的現象,不少自適應的兩欄佈局就是這麼作的。好比下圖的效果,參考例子ui

<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>
複製代碼

案例分析: 很明顯,.aside和.mian重疊了。試分析一下,因爲兩個box都處在同一個BFC中,都是以BFC邊界爲起點,若是兩個box自己都具有BFC的話,會按順序一個一個排列布局,如今.main並不具有BFC,根據BFC佈局規則第3條

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

雖然存在浮動的元素aslide,但main的左邊依然會與包含塊的左邊相接觸 根據BFC佈局規則第四條:3d

BFC的區域不會與float box重疊

咱們能夠經過經過觸發main生成BFC, 來實現自適應兩欄佈局

.main {
    overflow: hidden;
}
複製代碼

當觸發main生成BFC後,這個新的BFC不會與浮動的aside重疊。所以會根據包含塊的寬度,和aside的寬度,自動變窄。效果以下:

2. 清除元素內部浮動

案例代碼:

<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佈局規則第六條:

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

爲達到清除內部浮動,咱們能夠觸發par生成BFC,那麼par在計算高度時,par內部的浮動元素child也會參與計算。

.par{
  overflow:hidden
}
複製代碼

加入上面樣式,便可解決問題,效果以下:

3. 防止垂直 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重疊。根據BFC佈局規則第二條:

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

咱們能夠在p外面包裹一層容器,並觸發該容器生成一個BFC。那麼兩個P便不屬於同一個BFC,就不會發生margin重疊了。

<style>
    .wrap {
        overflow: hidden;
    }
    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>
複製代碼

效果以下:

按照BFC的定義,只有同屬於一個BFC時,兩個元素纔有可能發生垂直Margin的重疊,這個包括相鄰元素,嵌套元素,只要他們之間沒有阻擋(例如邊框,非空內容,padding等)就會發生margin重疊。 所以要解決margin重疊問題,只要讓它們不在同一個BFC就好了,可是對於兩個相鄰元素來講,意義不大,沒有必要給它們加個外殼,可是對於嵌套元素來講就頗有必要了,只要把父元素設爲BFC就能夠了。這樣子元素的margin就不會和父元素的margin發生重疊了。

部份內容來自BFC背後神奇的原理

相關文章
相關標籤/搜索