詳解BFC、IFC、GFC、FFC

無限迴圈無限發表於2020-04-07

Formatting Context(格式化上下文)

Formatting context 是 W3C CSS2.1 規範中的一個概念。它是頁面中的一塊渲染區域,並且有一套渲染規則,它決定了其子元素將如何定位,以及和其他元素的關係和相互作用。

BFC是一個獨立的佈局環境,其中的元素佈局是不受外界的影響,並且在一個BFC中,塊盒與行盒(行盒由一行中所有的內聯元素所組成)都會垂直的沿著其父元素的邊框排列。

Formatting Context(格式化上下文)包括

  1. BFC(塊級)
  2. IFC
  3. FFC
  4. GFC

BFC

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

BFC的佈局規則

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

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

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

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

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

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

如何建立BFC

  1. float的值不是none。
  2. position的值不是static或者relative。
  3. display的值是inline-block、table-cell、flex、table-caption或者inline-flex
  4. overflow的值不是visible

BFC的作用

  1. 利用BFC避免margin重疊。

IFC

IFC(Inline Formatting Contexts)直譯為"內聯格式化上下文",IFC的line box(線框)高度由其包含行內元素中最高的實際高度計算而來(不受到豎直方向的padding/margin影響) IFC中的line box一般左右都貼緊整個IFC,但是會因為float元素而擾亂。float元素會位於IFC與與line box之間,使得line box寬度縮短。 同個ifc下的多個line box高度會不同。 IFC中時不可能有塊級元素的,當插入塊級元素時(如p中插入div)會產生兩個匿名塊與div分隔開,即產生兩個IFC,每個IFC對外表現為塊級元素,與div垂直排列。 那麼IFC一般有什麼用呢? 水平居中:當一個塊要在環境中水平居中時,設定其為inline-block則會在外層產生IFC,通過text-align則可以使其水平居中。 垂直居中:建立一個IFC,用其中一個元素撐開父元素的高度,然後設定其vertical-align:middle,其他行內元素則可以在此父元素下垂直居中。

IFC佈局規則:

框會從包含塊的頂部開始,一個接一個地水平擺放。 擺放這些框的時候,它們在水平方向上的外邊距、邊框、內邊距所佔用的空間都會被考慮在內。在垂直方向上,這些框可能會以不同形式來對齊:它們可能會把底部或頂部對齊,也可能把其內部的文字基線對齊。能把在一行上的框都完全包含進去的一個矩形區域,被稱為該行的行框。水平的margin、padding、border有效,垂直無效。不能指定寬高。 行框的寬度是由包含塊和存在的浮動來決定。行框的高度由行高計算這一章所描述的規則來決定。

GFC

GFC(GridLayout Formatting Contexts)直譯為"網格佈局格式化上下文",當為一個元素設定display值為grid的時候,此元素將會獲得一個獨立的渲染區域,我們可以通過在網格容器(grid container)上定義網格定義行(grid definition rows)和網格定義列(grid definition columns)屬性各在網格專案(grid item)上定義網格行(grid row)和網格列(grid columns)為每一個網格專案(grid item)定義位置和空間。 那麼GFC有什麼用呢,和table又有什麼區別呢?首先同樣是一個二維的表格,但GridLayout會有更加豐富的屬性來控制行列,控制對齊以及更為精細的渲染語義和控制。

FFC

FFC(Flex Formatting Contexts)直譯為"自適應格式化上下文",display值為flex或者inline-flex的元素將會生成自適應容器(flex container),可惜這個牛逼的屬性只有谷歌和火狐支援,不過在移動端也足夠了,至少safari和chrome還是OK的,畢竟這倆在移動端才是王道。 Flex Box 由伸縮容器和伸縮專案組成。通過設定元素的 display 屬性為 flex 或 inline-flex 可以得到一個伸縮容器。設定為 flex 的容器被渲染為一個塊級元素,而設定為 inline-flex 的容器則渲染為一個行內元素。 伸縮容器中的每一個子元素都是一個伸縮專案。伸縮專案可以是任意數量的。伸縮容器外和伸縮專案內的一切元素都不受影響。簡單地說,Flexbox 定義了伸縮容器內伸縮專案該如何佈局。

參考