視覺格式化模型之BFC

情景:浮動的高度塌陷時,使用overflow:hidden可以使父元素將浮動的子元素包含起來,解決問題。但背後的原理是什麼?這就是今天要談的BFC。css

在將BFC以前須要先了解幾個概念: html

盒子模型(Box model):相信這個你們已經很瞭解了,這裏就不詳細說了。詳見《CSS權威指南》 ide

塊級元素:佈局

Block-level elements are those elements of the source document that are formatted visually as blocks (e.g., paragraphs). The following values of the 'display' property make an element block-level: 'block', 'list-item', and 'table'.學習

即塊級元素是源文檔中被格式化爲塊(block)的元素,或者display屬性爲:'block', 'list-item', and 'table'的元素。flex

塊級盒:ui

Block-level boxes are boxes that participate in a block formatting context. Each block-level element generates a principal block-level box that contains descendant boxes and generated content and is also the box involved in any positioning scheme.spa

塊級盒主要存在於BFC中,每一個塊級元素會產生主要的塊級盒,該盒包含其子框和生成的內容,同時會受到不一樣定位方案的影響。code

塊容器盒orm

Except for table boxes, and replaced elements,a block-level box is also a block container box. A block container box either contains only block-level boxes or establishes an inline formatting context and thus contains only inline-level boxes. Not all block container boxes are block-level boxes: non-replaced inline blocks and non-replaced table cells are block containers but not block-level boxes. Block-level boxes that are also block containers are called block boxes.

除了表格框和替換元素,其餘的塊級盒都是塊容器盒,塊容器盒要麼只包含塊級盒,要麼創建一個IFC(內行格式化上下文),並非全部的塊容器盒都是塊級盒:非替代inline-block和非替代table cells是塊容器盒但不是塊級盒。既是塊級盒又是快容器盒的叫作塊盒
一下是塊級盒、塊盒和塊容器盒三者的關係
圖片描述

正常流:不管是塊級盒或者是行內盒在正常流都屬於格式化上下文,塊級盒存在於BFC,行內盒存在於IFC,因此,正常流格式化上下文中包含BFC和IFC(行內格式化上下文,另外一種格式化上下文)。

概念

BFC(Block formatting contexts):顧名思義塊級格式化上下文。通俗的說,它是一個獨立的渲染區域,裏面只有Block-level box,並規定他們的佈局方式,與其餘區域互不影響。

BFC的生成

  1. 根元素或其它包含它的元素

  2. 浮動 (元素的 float 不爲 none)

  3. 絕對定位元素 (元素的 position 爲 absolute 或 fixed)

  4. 行內塊 inline-blocks (元素的 display: inline-block)

  5. 表格單元格 (元素的 display: table-cell,HTML表格單元格默認屬性)

  6. 表格標題 (元素的 display: table-caption, HTML表格標題默認屬性)

  7. overflow 的值不爲 visible的元素

  8. 彈性盒子 flex boxes (元素的 display: flex 或 inline-flex)

BFC佈局規則

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

  2. Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊。若是相鄰有一個是BFC的話,則BFC裏面的子元素margin與外面的Box的margin不重疊。

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

  4. BFC的區域不會與float box重疊,經常使用來清除浮動和佈局。

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

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

BFC應用

1.防止margin值重疊(佈局規則2)

舉個例子:

<!DOCTYPE html>
<html>
<head>
    <title>BFC</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
     <div class="red"></div>
     <div class="black"></div>
</body>
</html>
body{padding:0;margin:0}
        .red{
            background:red ;
            width:200px;
            height: 200px;
            margin: 10px;          
        }

        .black{
            background:black ;
            width:200px;
            height: 200px;
            margin: 10px;
        }

結果margin重疊:
圖片描述

讓紅色方塊變成BFC後:

<!DOCTYPE html>
<html>
<head>
    <title>BFC之防止margin重疊</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
    <div class="wrap">
         <div class="red"></div>
    </div>
     <div class="black"></div>
</body>
</html>
body{padding:0;margin:0}
        .red{
            background:red ;
            width:200px;
            height: 200px;
            margin: 10px;          
        }
        .wrap{overflow: hidden;}
        .black{
            background:black ;
            width:200px;
            height: 200px;
            margin: 10px;
        }

結果margin不重疊
圖片描述

2.清除浮動
父元素包含浮動子元素(所有)時,高度會出現坍塌。

<!DOCTYPE html>
<html>
<head>
    <title>BFC</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
    <div class="wrap">
         <div class="red"></div>
          <div class="black"></div>
     </div>
</body>
</html>
body{padding:0;margin:0}
        .wrap{
            width: 500px;
            border: blue solid 2px;
        }
        .red{
            border: red solid 1px;
            width:200px;
            height: 200px;
            float: left;         
        }
        
        .black{
            border: black solid 1px;
            width:200px;
            height: 200px;
            float: right;

        }

結果:圖片描述

給父元素添加overflow: hidden;後父元素變成BFC,根據佈局規則6,父元素會將子元素包含在內。

<!DOCTYPE html>
<html>
<head>
    <title>BFC</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
    <div class="wrap">
         <div class="red"></div>
          <div class="black"></div>
     </div>
</body>
</html>
body{padding:0;margin:0}
        .wrap{
            width: 500px;
            border: blue solid 2px;
            overflow: hidden;
        }
        .red{
            border: red solid 1px;
            width:200px;
            height: 200px;
            float: left;         
        }
        
        .black{
            border: black solid 1px;
            width:200px;
            height: 200px;
            float: right;

        }

結果圖片描述

3.兩欄自適應佈局
若是左欄設置爲浮動,右邊一欄正常顯示,則會將浮動會蓋住右邊。

![clipboard.png](/img/bVHIZZ)
l>
<html>
<head>
    <title>BFC</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
         <div class="left"></div>
          <div class="main"></div>
</body>
</html>
body{padding:0;margin:0}

        .left{
            border: red solid 1px;
            width:200px;
            height: 200px;
            float: left;         
        }
        
        .main{
            border: black solid 1px;
            width:250px;
            height: 250px;
            

        }

結果
圖片描述

給main那一欄添加 overflow: hidden;後變成BFC(根據佈局規則2)。

<!DOCTYPE html>
<html>
<head>
    <title>BFC</title>
    <meta charset="utf-8">
    <link rel="stylesheet" type="text/css" href="index.css">
</head>
<body>
         <div class="left"></div>
          <div class="main"></div>
</body>
</html>
body{padding:0;margin:0}

        .left{
            border: red solid 1px;
            width:200px;
            height: 200px;
            float: left;         
        }
        
        .main{
            border: black solid 1px;
            width:250px;
            height: 250px;
            overflow: hidden;
            
        }

結果
圖片描述

思考與總結

由於根元素就是一個BFC,文檔中塊級盒的佈局規則符合BFC,因此書裏面寫的文檔流是從上到下的排列、相鄰塊級之間的margin會發生重疊,浮動會自動造成block等知識點,其實在這裏就能找到答案。包括清除浮動、兩欄自適應佈局的原理也清晰明瞭。所以掌握BFC原理也掌握另外一種解決問題的思路。
這裏有點建議就是儘可能閱讀官網的資料,裏面的內容最準確,最權威。

以上是我粗淺的理解,若是哪裏有問題,請幫忙指出,有未涉及的知識點,歡迎補充。一塊兒學習,共同進步。

參考

https://www.w3.org/TR/2011/RE...

https://developer.mozilla.org...

http://www.yangyong.me/css2-b...

相關文章
相關標籤/搜索