重拾 CSS 之 BFC

程式設計之上發表於2019-07-07

BFC 為何物

格式化上下文(Block Formatting Context),是 Web 頁面中盒模型佈局的 CSS 渲染模式,主要指一個獨立的渲染區域或一個隔離的獨立容器。

需要什麼條件(即如何脫離文件流)

  • 根元素(HTML元素),最大的一個BFC;
  • 浮動元素,floatnone 以外的值;
  • 定位元素,position: [absolute | fixed]
  • display: [inline-block | table-cell | table-caption]
  • overflow: [hidden | auto | scroll], 即除 visible 以外的值;

看例子

BFC 中的盒子對齊垂直存放

重拾 CSS 之 BFC

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>BFC 對齊</title>
    <style>
        * { margin: 0; padding: 0; }
        .absolute { position: absolute; }
        .left { float: left; }
        .section { width: 520px; }
        .section1 { background-color: red; min-height: 40px; }
        .section2 { background-color: orange; min-height: 40px; }
        .section3 { background-color: yellow; width: 100px; min-height: 40px; }
        .section4 { background-color: green;  min-height: 60px; }
    </style>
</head>

<body>
    <div class="section">
        <div class="section1">section1</div>
        <div class="section2">section2</div>
        <div class="section3 left">section3 float</div>
        <div class="section4">section4</div>
    </div>
</body>

</html>
複製程式碼

哪怕浮動元素(section3)也接著上一個盒子垂直排列(所有的盒子都左對齊)。

外邊距摺疊

重拾 CSS 之 BFC

例子1

重拾 CSS 之 BFC

例子2

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>BFC margin</title>
    <style>
        * { margin: 0; padding: 0; }
        .hidden { overflow: hidden; }
        .section { margin: 20px auto; border:1px solid red; width: 800px; }
        .section1 { background-color: orange; margin: 10px; min-height: 40px; }
        .section2 { background-color: green; margin: 30px; min-height: 60px; }
    </style>
</head>

<body>
    <div class="section">
        <div class="section1"></div>
        <div class="section2"></div>
    </div>

    <div class="section">
        <div class="hidden">
            <div class="section1"></div>
        </div>
        <div class="section2"></div>
    </div>
</body>

</html>
複製程式碼

例子1:兩個內部盒子 section1section2 的垂直距離為 30px 而不是 40px,因為垂直外邊距會摺疊,間距以較大的為準;

例子2:如何解決垂直外邊距不折疊呢?其實只要讓 BFC 容器裡的元素不會影響外面元素,同樣外面元素不影響 BFC 容器裡的元素,即讓 section1section2 中一個盒子處於一個 BFC 容器中就行了;

不被浮動元素覆蓋

重拾 CSS 之 BFC

例子1

重拾 CSS 之 BFC

例子2 和 例子3

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>BFC float</title>
    <style>
        * { margin: 0; padding: 0; }
        .hidden{ overflow: auto;}
        .left { float: left; }
        .right { float: right; }
        .section { margin: 20px auto; border: 1px solid red; width: 800px; }
        .section1 { background-color: orange; width: 100px; min-height: 40px; margin-right: 10px; }
        .section2 { min-height: 60px; background-color: green;}
        .section3 { background-color: pink; width: 100px; min-height: 40px;  margin-left: 10px; }
    </style>
</head>

<body>
    <div class="section">
        <div class="section1 left">
            <p>section1</p>
            <p>section1</p>
        </div>
        <div class="section2">
            <p>section2</p>
            <p>section2</p>
            <p>section2</p>
            <p>section2</p>
        </div>
    </div>

    <div class="section">
        <div class="section1 left">
            <p>section1</p>
            <p>section1</p>
        </div>
        <div class="section2 hidden">
            <p>section2</p>
            <p>section2</p>
            <p>section2</p>
            <p>section2</p>
        </div>
    </div>

    <div class="section">
        <div class="section1 left">
            <p>section1</p>
            <p>section1</p>
        </div>
        <div class="section3 right">
            <p>section3</p>
            <p>section3</p>
        </div>
        <div class="section2 hidden">
            <p>section2</p>
            <p>section2</p>
            <p>section2</p>
            <p>section2</p>
        </div>
    </div>
</body>

</html>
複製程式碼
  • 例子1:字型環繞,浮動的盒子會遮蓋下面的盒子,但是下面盒子裡的文字是不會被遮蓋的,文字反而還會環繞浮動的盒子(挺有有趣的),如何阻止文字環繞,可看例子2;
  • 例子2:兩欄佈局,左邊固定寬度,右邊不設寬(寬度自適應,隨瀏覽器視窗大小的變化而變化);
  • 例子3:三欄佈局,左右兩邊固定寬度,中間不設寬(寬度自適應,隨瀏覽器的大小變化而變化);

BFC 包含浮動的塊

其實就是清浮動(利用 overflow:hidden),可看面試之道之 CSS 佈局

最後

總結下特徵(能解決哪些問題)

  • 內部的 box 在垂直方向存放;
  • 垂直方向上的距離由 margin 決定(外間距之和);
  • BFC 的區域不會與 float 元素區域重疊(阻止文字環繞和實現多欄佈局);
  • 計算 BFC 的高度時,浮動元素也參與計算(清浮動);
  • bfc 是頁面上的一個獨立容器,容器裡的子元素不會影響外面元素;

本次程式碼 Github

相關文章