CSS中各類佈局的背後,實質上是各類*FC的組合。CSS2.1 中只有 BFC 和 IFC, CSS3 中還增長了 FFC 和 GFC。
盒模型(Box Model)
.png)html
上圖爲W3C標準盒模型,另外還有一種IE盒模型(IE6如下),惟一的區別就是:前者
width = content
,後者
width = content + padding + border
若要將IE盒模型轉換爲標準盒模型,須要在文檔頂部加上<!DOCTYPE html>
聲明;頗有意思的是,後來CSS3 中也增長了box-sizing
屬性,box-sizing: content-box
即標準盒模型,box-sizing: border-box
即IE盒模型(width包含內邊距和邊框),W3C反過來又認可了微軟,也是有意思。api
視覺格式化模型(Visual Formatting Model)
視覺格式化模型(visual formatting model)是用來處理文檔並將它顯示在視覺媒體上的機制,根據上述的盒模型,爲文檔元素生成盒(Box)。通俗的說,視覺格式化模型就是文檔裏的盒子佈局呈現的一種規則。
影響佈局的因素瀏覽器
- 盒的尺寸和類型
- 定位方案
Positioning Scheme
(常規流,浮動和絕對定位)
- 文檔樹中元素之間的關係
- 外部信息(如:視口大小,圖片的固有尺寸等)
FC -- Formatting Context
FC...是誰在說髒話?! Formatting Context -- 格式化上下文,*FC就是視覺格式化模型,用來描述盒子佈局規則。
前方大波概念來襲!
塊級元素、塊級盒、塊容器盒、塊盒、匿名塊盒、行內級元素、行內級盒、原子行內級盒、原子行內盒、行盒、匿名行內盒、
插入盒......要報警了!!!這些真的不是我YY出來的,
W3C 裏真的有這麼多概念好嗎!!!感受進坑了啊!!!headache...來吧,一個個捋清楚... -_-|||
- 塊級元素(Block-level elements):當元素的 CSS 屬性
display:block / list-item / table
時,它就是是塊級元素 block-level ,視覺上呈現爲塊,豎直排列。每一個塊級元素生成一個主要的塊級盒 (Principal Block-level Box) 來包含其後代盒和生成的內容,同時參與定位體系 (Positioning Scheme) 。某些塊級元素還會在主要盒以外產生額外的盒: list-item 元素。這些額外的盒會相對於主要盒來擺放。
- 塊級盒(Block-level boxes):由塊級元素生成,參與塊級格式化上下文(BFC)。描述元素跟它的父元素與兄弟元素之間的表現。
- 塊容器盒(Block container box):只包含其它塊級盒,或生成一個行內格式化上下文(inline formatting context),只包含行內盒。有些塊級盒,好比表格,不是塊容器盒。相反,一些塊容器盒,好比非替換行內塊及非替換表格單元格,不是塊級盒。描述元素跟它的後代之間的影響。
- 塊盒(Block boxes):同時是塊容器盒的塊級盒。

- 匿名塊盒(Anonymous block boxes):沒有名字,不能被 CSS 選擇符選中。塊容器盒要麼只包含行內級盒,要麼只包含塊級盒,但一般文檔會同時包含二者,在這種狀況下,將建立匿名塊盒來包含毗鄰的行內級盒。
<div>
I am Block container box
<p>I'm Inline-level boxes</p>
I am Block container box
</div>
- 行內級元素(Inline-level elements):當元素的 CSS 屬性
display:inline, inline-block 或 inline-table
時,稱它爲行內級元素。行內級元素生成行內級盒(inline-level boxes),參與行內格式化上下文(IFC)。
- 行內級盒(Inline-level boxes):全部
display:inline
的非替換元素生成的盒是行內盒。
- 原子行內級盒(atomic inline-level boxes):不參與生成行內格式化上下文的行內級盒稱爲原子行內級盒(atomic inline-level boxes)。
- 原子行內盒(atomic inline boxes):注意:起初原子行內級盒(atomic inline-level boxes)被稱爲原子行內盒(atomic inline boxes)。很不幸,它們並不是行內盒。規範的勘誤表修正了這個錯誤。無論怎樣,當再看到原子行內盒時能夠放心的當成原子行內級盒,由於只是改了名字。原子行內盒在行內格式化上下文裏不能分紅多行。
- 行盒(Line boxes):行盒由行內格式化上下文(IFC)產生的盒,用於表示一行。在塊盒裏面,行盒從塊盒一邊排版到另外一邊。 當有浮動時, 行盒從左浮動的最右邊排版到右浮動的最左邊。

- 匿名行內盒(Anonymous inline boxes):匿名行內盒最多見的例子是塊盒直接包含文本。
-
插入盒(Run-in boxes):插入盒(Run-in boxes)從 CSS 2.1 標準中移除了,由於可操做的實現定義不足。 可能 CSS3 會引入,可是這是實驗性質,不能用於生產環境。
定位方案(Positioning schemes)
- 常規流(Normal flow)
CSS2.1中,常規流包括塊級盒的塊格式化,行內盒的行內格式化,以及塊級盒和行內級盒的相對定位。
- 浮動(Floats)
在浮動模型中,盒首先根據常規流佈局,而後從常規流中脫離並儘量地向左或向右位移。內容能夠佈局在浮動周圍。
- 絕對定位(Absolute positioning)
在絕對定位模型中,盒徹底從常規流中脫離(對後面的同胞元素無影響)並根據包含塊來分配位置。
BFC -- Block Formatting Context
觸發條件
- 根元素或其它包含它的元素
- 浮動
float: left/right/inherit
- 絕對定位元素
position: absolute/fixed
- 行內塊
display: inline-block
- 表格單元格
display: table-cell
- 表格標題
display: table-caption
- 溢出元素
overflow: hidden/scroll/auto/inherit
- 彈性盒子
display: flex/inline-flex
佈局規則
- 內部的Box會在垂直方向,一個接一個地放置。
- Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊。
- 每一個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此。
- BFC的區域不會與float box重疊。
- BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素。反之也如此。
- 計算BFC的高度時,浮動元素也參與計算
應用場景
- 閉合浮動:浮動區域不疊加到BFC區域上
- 防止與浮動元素重疊
- 防止margin collapse
- float 元素高度塌陷
- ...
IFC -- Inline Formatting Contexts
觸發條件
一個塊級元素中僅包含內聯級別元素ide
佈局規則
- 內部的盒子會在水平方向,一個接一個地放置。
- 這些盒子垂直方向的起點從包含塊盒子的頂部開始。
- 擺放這些盒子的時候,它們在水平方向上的 padding、border、margin 所佔用的空間都會被考慮在內。
- 在垂直方向上,這些框可能會以不一樣形式來對齊(vertical-align):它們可能會使用底部或頂部對齊,也可能經過其內部的文本基線(baseline)對齊。
- 能把在一行上的框都徹底包含進去的一個矩形區域,被稱爲該行的行框(line box)。行框的寬度是由包含塊(containing box)和存在的浮動來決定。
- IFC中的 line box 通常左右邊都貼緊其包含塊,可是會由於float元素的存在發生變化。float 元素會位於IFC與與 line box 之間,使得 line box 寬度縮短。
- IFC 中的 line box 高度由 CSS 行高計算規則來肯定,同個 IFC 下的多個 line box 高度可能會不一樣(好比一行包含了較高的圖片,而另外一行只有文本)
- 當 inline-level boxes 的總寬度少於包含它們的 line box 時,其水平渲染規則由 text-align 屬性來肯定,若是取值爲 justify,那麼瀏覽器會對 inline-boxes(注意不是inline-table 和 inline-block boxes)中的文字和空格作出拉伸。
- 當一個 inline box 超過 line box 的寬度時,它會被分割成多個boxes,這些 boxes 被分佈在多個 line box 裏。若是一個 inline box 不能被分割(好比只包含單個字符,或 word-breaking 機制被禁用,或該行內框受 white-space 屬性值爲 nowrap 或 pre 的影響),那麼這個 inline box 將溢出這個 line box。
應用場景
- 水平居中:當一個塊要在環境中水平居中時,設置其爲 inline-block 則會在外層產生 IFC,經過設置父容器 text-align:center 則可使其水平居中。
- 垂直居中:建立一個IFC,用其中一個元素撐開父元素的高度,而後設置其 vertical-align:middle,其餘行內元素則能夠在此父元素下垂直居中。
FFC -- Flex Formatting Contexts
觸發條件
當 display
的值爲 flex
或 inline-flex
時,將生成彈性容器(Flex Containers), 一個彈性容器爲其內容創建了一個新的彈性格式化上下文環境(FFC)佈局
佈局規則
- 設置爲
flex
的容器被渲染爲一個塊級元素
- 設置爲
inline-flex
的容器則渲染爲一個行內元素
- 彈性容器中的每個子元素都是一個彈性項目。彈性項目能夠是任意數量的。彈性容器外和彈性項目內的一切元素都不受影響。簡單地說,Flexbox 定義了彈性容器內彈性項目該如何佈局
GFC -- GridLayout Formatting Contexts
觸發條件
當爲一個元素設置display
值爲grid
的時候,此元素將會得到一個獨立的渲染區域flex
佈局規則
經過在網格容器(grid container)上定義網格定義行(grid definition rows)和網格定義列(grid definition columns)屬性各在網格項目(grid item)上定義網格行(grid row)和網格列(grid columns)爲每個網格項目(grid item)定義位置和空間ui
參考:atom
Visual formatting modelspa
視覺格式化模型code
BFC 神奇背後的原理