理解 CSS 中的 BFC

半掩時光發表於2019-05-07

BFC 即 Block Formatting Contexts (塊級格式化上下文),它是頁面中的一塊渲染區域,並且有一套渲染規則,它決定了其子元素將如何定位,以及和其他元素的關係和相互作用。

具有 BFC 特性的元素可以看作是隔離了的獨立容器,容器裡面的元素不會在佈局上影響到外面的元素,並且 BFC 具有普通容器所沒有的一些特性。

通俗一點來講,可以把 BFC 理解為一個封閉的大箱子,箱子內部的元素無論如何翻江倒海,都不會影響到外部。

觸發

只要元素滿足下面任一條件即可觸發 BFC :

  • body 根元素
  • 浮動元素:float 除 none 以外的值
  • 絕對定位元素:position (absolute、fixed)
  • display 為 inline-block、table-cells、flex
  • overflow 除了 visible 以外的值 (hidden、auto、scroll)

佈局特性

具備 BFC 屬性的元素,在頁面佈局上會有如下特性:

  • 內部的塊級 Box 會在垂直方向上挨個排列
  • 屬於同一個 BFC 的兩個相鄰 Box 的 margin 會發生重疊
  • 子元素的 margin 左邊界,與父容器的 border 左邊界是相接觸的,即使設定了浮動依然如此
  • 具備 BFC 的區域不會與浮動的 Box 發生重疊
  • BFC 就是頁面的一個隔離的獨立容器,容器裡面的子元素不會影響到外面的元素,反之亦然
  • 計算 BFC 的高度時,浮動元素也參與計算

應用

利用上述的這些 BFC 特性,我們可以總結出 BFC 具備如下的運用場景:

兩欄或三欄自適應佈局

以兩欄為例,如果不給 main 容器新增 overflow: hidden 屬性,main 容器會延展到浮動區域,使其成為 BFC 後,便可使其實現寬度自適應。

<div>
    <div class="float"></div>
    <div class="main"></div>
</div>

<style>
.float{
    width: 200px;
    height: 500px;
    background: skyblue;
    float: left;
}
.main{
    background: pink;
    height: 600px;
    overflow: hidden; /* 使其成為 BFC */
}
</style>

複製程式碼

完整程式碼-線上預覽

這個方法也可運用於解決一個元素被浮動元素覆蓋的問題,請戳-完整程式碼-線上預覽

解決父容器高度塌陷

我們知道浮動元素會脫離文件流,當父容器的所有子元素都設定浮動後,會導致父容器出現高度“塌陷”的問題,如果讓父容器設定為 BFC ,那麼它就會包裹浮動元素,從而解決高度“塌陷”:

<div class="wrap">
    <div class="box"></div>
    <div class="box"></div>
</div>

<style>
.wrap{
    border: 1px solid red;
    overflow: hidden; /* 使其成為 BFC */
}
.box{
    width: 50px;
    height: 50px;
    background: skyblue;
    float: left;
}
</style>

複製程式碼

完整程式碼-線上預覽

解決垂直方向 margin 重疊

從上述 BFC 的特性我們知道子元素垂直方向的距離由 margin 決定,屬於同一個 BFC 的兩個相鄰子元素的 margin 會發生重疊,解決辦法就是使這兩個相鄰的子元素分別屬於不同的 BFC:

<div class="wrap">
    <div class="box">1</div>
    <div class="inner">
        <div class="box">2</div>
    </div>
</div>

<style>
.box {
    width: 50px;
    height:50px;
    background: skyblue;
    margin: 50px;
}
.inner{
    overflow: hidden;
}
</style>

複製程式碼

這裡我們給其中一個 Box 外面包一個 div(即 inner 容器),然後通過觸發外面這個 div 的 BFC ,就可以阻止這兩個 Box 的 margin 重疊。

完整程式碼-線上預覽