1. 程式人生 > >BFC:塊級格式化上下文

BFC:塊級格式化上下文

1.盒模型和格式化上下文

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 中才有, 這兒先不講了。

Formatting context

  Formatting context 是 W3C CSS2.1 規範中的一個概念。它是頁面中的一塊渲染區域,並且有一套渲染規則,它決定了其子元素將如何定位,以及和其他元素的關係和相互作用。最常見的 Formatting context 有 Block fomatting context (簡稱BFC)和 Inline formatting context (簡稱IFC)。

  CSS2.1 中只有 BFC 和 IFC, CSS3 中還增加了 GFC 和 FFC。

BFC 定義

  BFC(Block formatting context)直譯為”塊級格式化上下文”。它是一個獨立的渲染區域,只有Block-level box參與, 它規定了內部的Block-level Box如何佈局,並且與這個區域外部毫不相干。

2.BFC的佈局特性

  1. BFC就是頁面上的一個隔離的獨立容器,容器裡面的子元素不會影響到外面的元素。反之也如此。
  2. 內部的塊級元素會在垂直方向,一個接一個地放置,依然保留塊級元素的流體特性
  3. Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊
  4. 每個塊級子元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。
  5. BFC的區域不會與float box重疊。(根據第1條可以推出,當BFC外部存在浮動時,它不應該影響BFC內部Box的佈局,BFC會通過變窄,而不與浮動有重疊)
  6. 計算BFC的高度時,浮動元素也參與計算

3.如何產生BFC

  • 根元素
  • 浮動元素(float屬性不為none)
  • position為absolute或fixed的元素(不推薦在自適應佈局中使用)
  • display為inline-block,table-cell, table-caption, flex, inline-flex,grid
  • overflow不為visible的塊元素(一般設定為overflow:hidden

4.BFC應用場景:兩列自適應佈局

左列不定寬或者定寬,右列自適應,兩列中間有間距,可以在區域性使用float+BFC:

首先考慮如果.right沒有指定overflow:hidden規則時的情況:
當right不建立BFC時,.left和.right都處於根元素.parent建立的BFC中,根據BFC佈局特性3:
每個塊級子元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,否則相反)。即使存在浮動也是如此。
那麼.left和.right都會靠在.parent的左邊border上,又因為.left使用了浮動,根據堆疊上下文規則,普通流後代塊元素會顯示在浮動塊元素的下面,因此.left塊元素顯示在.right塊元素的上面。為了讓.right和浮動.left分開,設定.right的overflow屬性為hidden觸發它的BFC特性:
BFC的區域不會與float box重疊。
那麼兩者就分成了兩列。為了產生間距,首先考慮的是margin,但是如果左邊不定寬不能設定.right的margin-left(同時注意如果設定值必須設定.left的寬度加上間距而不僅是間距,因為它仍舊是相對於容器邊緣進行設定的),可以設定float元素的margin-right或者是padding-right,如程式碼所示:
CSS:

        .left{
            float:left;
            margin-right:20px;/*距離右邊塊級元素20px*/
            width:100px;/*不定寬,可以不寫由內容決定*/
        }
        .right{
            overflow: hidden;   /*right變成BFC*/
        }

HTML:

<div class="parent">
            <div class="left">
                left
            </div>
            <div class="right">
                right
            </div>
        </div>

這裡寫圖片描述

BFC的其他應用場景包括:
清除內部浮動(計算BFC的高度時,浮動元素也參與計算,當父元素包含浮動元素時,觸發父元素的BFC特性可以讓父元素高度由浮動元素參與計算)
防止垂直margin的重疊(Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊,那麼可以通過讓其中一個Box觸發BFC特性來避免margin重疊)

5.BFC佈局優點

  • 自適應內容由於封閉,更健壯,容錯性強。比方說,內部clear:both不會與兄弟float產生矛盾。而純流體佈局,clear:both會讓後面內容無法和float元素在一個水平上,產生布局問題。
  • 自適應內容自動填滿浮動剩餘區域,無需關心浮動元素寬度,可以整站大規模應用。而純流體佈局,需要大小不確定的margin/padding等值撐開合適間距,無法CSS元件化。

6.參考