對於BFC(block format context)理解

前言

什麼是BFC?
在解釋 BFC 是什麼以前,須要先介紹Box(塊級,行級...)、FormattingContext的概念。css3

Box: CSS佈局的基本單位&盒模型

盒模型--塊級盒/行內盒

一個盒包括了內容(content)、邊(border)、內邊距(padding)、外邊距(margin)。下圖展現了盒模型的直觀意義:chrome

Image illustrating the relationship between content, padding, borders, and margins.

盒的尺寸(width與height--計算獲得的offsetWidth和offsetHeight)定義受到box-sizing屬性的影響。box-sizing可選擇content-box(默認)和border-box兩種模式。分別表明兩種盒子模型:W3c標準盒模型和IE盒子模型。ie8後開始支持經過CSS3屬性box-sizing,讓咱們能夠自由選擇採用哪一種盒子。佈局

w3c標準盒模型--塊級盒

width = content-width + padding-width + border-width
height = content-height + padding-height + border-height
IE盒子模型--塊級盒

width = content-width
height = content-height
行內盒

1.width、height不起做用,盒子高度由內容決定(font-size/line-height)決定
2.margin-top/margin-bottom/padding-top/padding-bottom不起做用flex

小結:code

  • 兩類塊級盒子可用過設置box-sizing轉換。
  • 行內盒與塊級盒轉換可經過設置display屬性來修改。下文將具體說明那些屬性生成塊級盒,哪些生成行內盒
  • 行內盒參與IFC佈局,塊級盒參與BFC佈局,若是塊級盒包含行內盒,可是因爲BFC內只有塊級盒參與,所以行內盒會被匿名塊級盒包含。

BOX

Box 是 CSS 佈局的對象和基本單位, 直觀點來講,就是一個頁面是由不少個 Box 組成的。元素的類型和 display 屬性,決定了這個 Box 的類型。 不一樣類型的 Box, 會參與不一樣的 Formatting Context(一個決定如何渲染文檔的容器),所以Box內的元素會以不一樣的方式渲染。讓咱們看看有哪些盒子:orm

盒子 解釋
block-level box的display 屬性爲block, list-item, table 的元素,會生成 block-level box。而且參與(BFC)block fomatting context;
inline-level box的display 屬性爲inline, inline-block, inline-table 的元素,會生成 inline-level box。而且參與 inline formatting context;
run-in box css3 中才有, 這兒先不講了。

格式化上下文

格式化上下文( formatting contexts )
├── 塊級格式化上下文( Block formatting contexts )( BFC )
├── 行內格式化上下文( Inline formatting contexts ) ( IFC )
├── 自適應格式化上下文( Flex Formatting Contexts )( FFC )
└── 網格佈局格式化上下文( GridLayout Formatting Contexts )( GFC )對象

有一類盒被稱爲塊容器,它們可以包含塊級盒。塊容器要麼建立BFC,這樣它內部僅僅包含塊級盒,要麼建立一個IFC,這樣它內部僅僅包含行內級元素。(也就是說,塊容器中不可能既包含塊級盒,又包含行內級盒,一旦他的子盒中有塊級盒,全部行內級盒都會被自動建立匿名盒包裹)。blog

在非塊級格式化上下文中的塊容器老是會建立新的BFC:如display爲inline-blocks, table-cells, 和table-captions所生成的盒。而自身也在塊級格式化上下文中的塊容器,則只有overflow不爲visible的情形下才會建立新的BFC。ip

絕對定位和浮動的塊容器則老是會建立新的塊級格式化上下文。

display值爲table或者inline-table的元素將會生成表格(table),表格內部會使用特殊的格式化方式來排布其內部元素。

display值爲grid或者inline-grid的元素將會生成格元素(grid element),與table情形相似,它內部也是使用特殊的格式化方式來牌不其內部元素,

display值爲flex或者inline-flex的元素將會生成自適應容器(flex container),自適應容器在其內部產生自適應格式化上下文(flex formatting context)

What's FC?
FC的全稱是:Formatting Contexts,是W3C CSS2.1規範中的一個概念。它是頁面中的一塊渲染區域,而且有一套渲染規則,它決定了其子元素將如何定位,以及和其餘元素的關係和相互做用。

格式化上下文 定義 應用
BFC BFC(Block Formatting Contexts)直譯爲"塊級格式化上下文"。Block Formatting Contexts就是頁面上的一個隔離的渲染區域,容器裏面的子元素不會在佈局上影響到外面的元素,反之也是如此。 如何產生BFC?float的值不爲none。overflow的值不爲visible。 position的值不爲relative和static。display的值爲table-cell, table-caption, inline-block中的任何一個。 那BFC通常有什麼用呢?好比常見的多欄佈局,結合塊級別元素浮動,裏面的元素則是在一個相對隔離的環境裏運行。
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,其餘行內元素則能夠在此父元素下垂直居中。
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 定義了伸縮容器內伸縮項目該如何佈局。

什麼是BFC?(Block formatting contexts)

w3c規範定義:

浮動元素和絕對定位元素,非塊級盒子的塊級容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不爲「visiable」的塊級盒子,都會爲他們的內容建立新的BFC(塊級格式上下文)。

BFC的通俗理解:

首先BFC是一個名詞,是一個獨立的佈局環境,咱們能夠理解爲一個箱子(其實是看不見摸不着的),箱子裏面物品的擺放是不受外界的影響的。轉換爲BFC的理解則是:BFC中的元素的佈局是不受外界的影響(咱們每每利用這個特性來消除浮動元素對其非浮動的兄弟元素和其子元素帶來的影響。)而且在一個BFC中,塊盒與行盒(行盒由一行中全部的內聯元素所組成,並不是指一個行內元素就產生一個行盒)都會垂直的沿着其父元素的邊框排列

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

BFC佈局規則:

  1. 內部的Box會在垂直方向,一個接一個地放置。
  2. Box垂直方向的距離由margin決定。屬於同一個BFC的兩個相鄰Box的margin會發生重疊
  3. 每一個元素的margin box的左邊, 與包含塊border box的左邊相接觸(對於從左往右的格式化,不然相反)。即便存在浮動也是如此。
  4. BFC的區域不會與float box重疊。
  5. BFC就是頁面上的一個隔離的獨立容器,容器裏面的子元素不會影響到外面的元素。反之也如此。
  6. 計算BFC的高度時,浮動元素也參與計算

那些元素生成BFC

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

元素與盒

在HTML中經常使用的概念是元素,而在CSS中,佈局的基本單位是盒,盒老是矩形的。

元素與盒並不是一一對應的關係,一個元素可能生成多個盒,CSS規則中的僞元素也可能生成盒,display屬性爲none的元素則不生成盒。

除了元素以外,HTML中的文本節點也可能會生成盒。

正常流

正常流是頁面,大部分盒排佈於正常流中。正常流中的盒一定位於某一格式化上下文中,正常流中有兩種格式化上下文:塊級格式化上下文(block formatting context,簡稱BFC)和行內格式化上下文(inline formatting context,IFC)。

在塊級格式化上下文中,盒呈縱向排布,在行內格式化上下文中,盒則呈橫向排布。

正常流根容器中是塊級格式化上下文,不一樣的盒可能會在內部產生行內格式化上下文或者塊級格式化上下文。

塊級與行內級

正常流中的盒分爲塊級與行內級兩種,任何一個行內級盒都不可以直接被放入塊級格式化上下文中。若是有一個HTML元素生成了一個行內盒,而其所在的上下文是塊級的話,那麼應當爲它生成一個匿名塊級盒,匿名塊級盒會在內部生成行內格式化上下文。

元素的display屬性會決定盒是行內級仍是塊級:

  • block, table, flex, grid, list-item 爲塊級
  • inline, inline-block, inline-table, inline-flex, inline-grid 爲行內級

產生垂直外邊距合併的必備條件

兩個margin是鄰接的必須知足如下條件:

  • 必須是處於常規文檔流(非float和絕對定位)的塊級盒子,而且處於同一個BFC當中。
  • 沒有線盒,沒有空隙(clearance,下面會講到),沒有padding和border將他們分隔開
  • 都屬於垂直方向上相鄰的外邊距,能夠是下面任意一種狀況
    • 元素的margin-top與其第一個常規文檔流的子元素的margin-top
    • 元素的margin-bottom與其下一個常規文檔流的兄弟元素的margin-top
    • height爲auto的元素的margin-bottom與其最後一個常規文檔流的子元素的margin-bottom
    • 高度爲0而且最小高度也爲0,不包含常規文檔流的子元素,而且自身沒有創建新的BFC的元素的margin-top和margin-bottom

最後來看張圖慢慢領會

相關文章
相關標籤/搜索