1. 程式人生 > >BFC外邊距穿透分析

BFC外邊距穿透分析

1.什麼是BFC?

BFC(Block Formatting Context):塊級格式化上下文。可以把它理解成一個獨立的區域。只有Block-level box參與, 它規定了內部的Block-level Box如何佈局,並且與這個區域外部毫不相干。

Block-level Box:

塊級盒block-level box是這種參與了塊級排版上下文的一種盒子,每個塊級元素都生成了一個包含後代盒子和生成的內容的主要塊級盒,並且這個盒子參與了任何定位的計算

2.BFC的定義

BFC是 W3C CSS 2.1 規範中的一個概念,它決定了元素如何對其內容進行定位,以及與其他元素的關係和相互作用。當涉及到視覺化佈局的時候,Block Formatting Context提供了一個環境,HTML元素在這個環境中按照一定規則進行佈局。一個環境中的元素不會影響到其它環境中的佈局。比如浮動元素會形成BFC,浮動元素內部子元素的主要受該浮動元素影響,兩個浮動元素之間是互不影響的。這裡有點類似一個BFC就是一個獨立的行政單位的意思。也可以說BFC就是一個作用範圍。可以把它理解成是一個獨立的容器,並且這個容器的裡box的佈局,與這個容器外的毫不相干。

3.BFC的佈局規則

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

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

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

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

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

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

4.哪些元素會產生BFC?

  1. 根元素
  2. float屬性不為none
  3. position為absolute或fixed
  4. display為inline-block, table-cell, table-caption, flex, inline-flex
  5. overflow不為visible

5.BFC的作用以及原理

1.自適應兩欄佈局:

程式碼:

    <style>
        body{
            width: 300px;
            position: relative;
        }
        .aside{
            width: 100px;
            height: 150px;
            float: left;
            background: rgb(5, 91, 250);
        }
        .main{
            height: 200px;
            background: rgb(124, 22, 207);
            /* 清除浮動 */
            /* overflow: hidden; */
        }
    </style>
</head>
<body>
    <div class="aside"></div>
    <div class="main"></div>
</body>

 頁面: 

每個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。因此,雖然存在浮動的元素aslide,但main的左邊依然會與包含塊的左邊相接觸。BFC的區域不會與float box重疊。

我們可以通過通過觸發main生成BFC, 來實現自適應兩欄佈局。

上面程式碼的.main裡面的overflow: hidden; 解開註釋。

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

效果圖:

 

2.清除內部浮動

程式碼:

    <style>
        .par{
            border: 5px solid rgb(189, 3, 179);
            width: 300px;
            /* overflow: hidden; */
        }
        .child{
            border: 5px solid rgb(70, 7, 218);
            width: 100px;
            height: 100px;
            float: left;
        }
    </style>
</head>
<body>
    <div class="par">
        <div class="child"></div>
        <div class="child"></div>
    </div>
</body>

頁面:

 

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

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

程式碼就是上面的.par裡面的overflow: hidden解開註釋

效果圖:

 

3. 防止垂直margin重疊

程式碼:

    <style>
        p{
            color: rgb(225, 31, 243);
            background: rgb(104, 10, 211);
            width: 200px;
            /* 定義行高 */
            line-height: 100px;
            text-align: center;
            margin: 100px;
        }
    </style>
</head>
<body>
    <p>Haha</p>
    <p>Hehe</p>
</body>

頁面:

 

兩個p之間的距離為100px,傳送了margin重疊。Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊 。

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

程式碼如下:

    <style>
        .wrap{
            overflow: hidden;
        }
        p{
            color: rgb(225, 31, 243);
            background: rgb(104, 10, 211);
            width: 200px;
            /* 定義行高 */
            line-height: 100px;
            text-align: center;
            margin: 100px;
        }
    </style>
</head>
<body>
    <p>Haha</p>
    <div class="wrap">
        <p>Hehe</p>
    </div>

效果圖:

 

總結: 

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

 因為BFC內部的元素和外部的元素絕對不會互相影響,因此, 當BFC外部存在浮動時,它不應該影響BFC內部Box的佈局,BFC會通過變窄,而不與浮動有重疊。同樣的,當BFC內部有浮動時,為了不影響外部元素的佈局,BFC計算高度時會包括浮動的高度。避免margin重疊也是這樣的一個道理。