多是最好的BFC解析了...

Tips:掘進以前的 BUG 致使文章被刪除了,評論也消失了,補發一下html

全文約 3000 字,閱讀完大約須要 6 分鐘,配合示例食用更佳git

BFC(Block Formatting Contexts),塊級格式化上下文,是 CSS 中一個比較晦澀難懂的概念,下面咱們嘗試以通俗易懂的語言完全地理解它。github

盒模型

CSS 盒模型描述了經過 文檔樹中的元素 以及相應的 視覺格式化模型 所生成的矩形盒子。簡單來講,盒模型定義了一個 矩形盒子,當咱們須要對文檔進行佈局時,瀏覽器的渲染引擎就會根據盒模型,將全部元素表示爲一個個矩形的盒子,盒子的外觀由 CSS 決定。瀏覽器

一個標準的盒子由四個部分組成,由內向外分別爲:內容內邊距邊框外邊距markdown

boxmodel-3.png

標準的盒模型中,內容區域的大小能夠明確地經過 widthmin-widthmax-widthheightmin-heightmax-height 控制,也就是說,經過 CSS 設置的元素寬高只是包含內容區域。你可能據說過 怪異盒模型,這種盒模型最先在 IE 瀏覽器中出現,也叫 IE盒模型box-sizing 屬性值爲 border-box 時,元素會呈現怪異盒模型,此時,元素的寬高包含了內容,內邊距和邊框ide

視覺格式化模型

CSS 視覺格式化模型描述了盒子是怎樣生成的,簡單來講,它定義了盒子生成的計算規則,經過規則將文檔元素轉換爲一個個盒子。oop

每個盒子的佈局由尺寸類型定位盒子的子元素或兄弟元素視口的尺寸和位置等因素決定。佈局

視覺格式化模型的計算,取決於一個矩形的邊界,這個矩形邊界,就是 包含塊( containing block ) ,好比:flex

<table>
  <tr>
    <td></td>
  </tr>
</table>
複製代碼

上述代碼片斷中,tabletr 都是包含塊,tabletr 的包含塊,同時 tr 又是 td 的包含塊。ui

須要注意的是,盒子不受包含塊的限制,當盒子的佈局跑到包含塊的外面時,就是咱們說的溢出(overflow)

視覺格式化模型定義了盒(Box)的生成,其中的盒主要包括了塊級盒,行內盒匿名盒

塊級元素

CSS 屬性值 displayblocklist-itemtable 的元素。

塊級盒

塊級盒具備如下特性:

  • CSS 屬性值 displayblocklist-itemtable 時,它就是塊級元素
  • 視覺上,塊級盒呈現爲豎直排列的塊
  • 每一個塊級盒都會參與 BFC 的建立
  • 每一個塊級元素都會至少生成一個塊級盒,稱爲主塊級盒;一些元素可能會生成額外的塊級盒,好比 <li>,用來存放項目符號

行內級元素

CSS 屬性值 displayinlineinline-blockinline-table 的元素。

行內盒

行內盒具備如下特性:

  • CSS 屬性值 displayinlineinline-blockinline-table 時,它就是行內級元素
  • 視覺上,行內盒與其餘行內級元素排列爲多行
  • 全部的可替換元素(display 值爲 inline,如 <img><iframe><video><embed> 等)生成的盒都是行內盒,它們會參與 IFC(行內格式化上下文) 的建立
  • 全部的非可替換行內元素(display 值爲 inline-blockinline-table)生成的盒稱爲原子行內級盒,不參與 IFC 建立

匿名盒

匿名盒指不能被 CSS 選擇器選中的盒子,好比:

<div>
  匿名盒1
  <p>塊盒</p>
  匿名盒2
</div>
複製代碼

上述代碼片斷中,div 元素和 p 元素都會生成一個塊級盒,p 元素的先後會生成兩個匿名盒。

匿名盒全部可繼承的 CSS 屬性值都爲 inherit,全部不可繼承的 CSS 屬性值都爲 initial

定位方案

CSS 頁面佈局技術容許咱們拾取網頁中的元素,而且控制它們相對正常佈局流(普通流)、周邊元素、父容器或者主視口/窗口的位置。技術佈局從宏觀上來講是受定位方案影響,定位方案包括普通流(Normal Flow,也叫常規流,正常佈局流),浮動(Float),定位技術(Position)。

普通流

瀏覽器默認的 HTML 佈局方式,此時瀏覽器不對頁面作任何佈局控制,

positionstaticrelative,而且 floatnone 時會觸發普通流,普通流有如下特性:

  • 普通流中,全部的盒一個接一個排列
  • BFC 中,盒子會豎着排列
  • IFC 中,盒子會橫着排列
  • 靜態定位中(positionstatic),盒的位置就是普通流里布局的位置
  • 相對定位中(positionrelative),盒的偏移位置由 toprightbottomleft 定義, 即便有偏移,仍然保留原有的位置,其它普通流不能佔用這個位置

浮動

  • 浮動定位中,盒稱爲浮動盒(Floating Box)
  • 盒位於當前行的開頭或結尾
  • 普通流會環繞在浮動盒周圍,除非設置 clear 屬性

定位技術

定位技術容許咱們將一個元素從它在頁面的原始位置準確地移動到另一個位置,有四種:靜態定位相對定位絕對定位固定定位

靜態定位

默認的定位方式(positionstatic),此時元素處於普通流中。

相對定位

相對定位一般用來對佈局進行微調,positionrelative 時,元素使用相對定位,此時能夠經過 toprightbottomleft 屬性對元素的位置進行微調,設置其相對於自身的偏移量

絕對定位

絕對定位方案中,盒會從普通流中移除,不會影響其餘普通流的佈局。絕對定位具備如下特色:

  • 元素的屬性 positionabsolutefixed 時,它是絕對定位元素
  • 它的定位相對於它的包含塊,能夠經過 toprightbottomleft 屬性對元素的位置進行微調,設置其相對於包含塊的偏移量
  • positionabsolute 的元素,其定位將相對於最近的一個 relativefixedabsolute 的父元素,若是沒有則相對於 body

固定定位

與絕對定位方案相似,惟一的區別在於,它的包含塊是瀏覽器視窗

塊級格式化上下文

經過對 CSS 盒模型,定位,佈局等知識的瞭解,咱們知道 BFC 這個概念其實來自於視覺格式化模型

它是頁面 CSS 視覺渲染的一部分,用於決定塊級盒的佈局及浮動相互影響範圍的一個區域

BFC 的建立

如下元素會建立 BFC

  • 根元素(<html>
  • 浮動元素(float 不爲 none
  • 絕對定位元素(positionabsolutefixed
  • 表格的標題和單元格(displaytable-captiontable-cell
  • 匿名錶格單元格元素(displaytableinline-table
  • 行內塊元素(displayinline-block
  • overflow 的值不爲 visible 的元素
  • 彈性元素(displayflexinline-flex 的元素的直接子元素)
  • 網格元素(displaygridinline-grid 的元素的直接子元素)

以上是 CSS2.1 規範定義的 BFC 觸發方式,在最新的 CSS3 規範中,彈性元素和網格元素會建立 F(Flex)FCG(Grid)FC

BFC 的範圍

A block formatting context contains everything inside of the element creating it, that is not also inside a descendant element that creates a new block formatting context.

直譯過來就是,BFC 包含建立它的元素的全部子元素,可是不包括建立了新的 BFC 的子元素的內部元素。

簡單來講,子元素若是又建立了一個新的 BFC,那麼它裏面的內容就不屬於上一個 BFC 了,這體現了 BFC 隔離 的思想,咱們仍是以 table 爲例:

<table>
  <tr>
    <td></td>
  </tr>
</table>
複製代碼

假設 table 元素建立的 BFC 咱們記爲 BFC_tabletr 元素建立的 BFC 記爲 BFC_tr,根據規則,兩個 BFC 的範圍分別爲:

  • BFC_trtd 元素
  • BFC_table:只有 tr 元素,不包括 tr 裏的 td 元素

也就是所說,一個元素不能同時存在於兩個 BFC 中

BFC 的特性

BFC 除了會建立一個隔離的空間外,還具備如下特性,附 CodePen 示例連接地址,可結合示例進行理解

  • BFC 內部的塊級盒會在垂直方向上一個接一個排列
  • 同一個 BFC 下的相鄰塊級元素可能發生外邊距摺疊,建立新的 BFC 能夠避免的外邊距摺疊
  • 每一個元素的外邊距盒(margin box)的左邊與包含塊邊框盒(border box)的左邊相接觸(從右向左的格式化,則相反),即便存在浮動也是如此
  • 浮動盒的區域不會和 BFC 重疊
  • 計算 BFC 的高度時,浮動元素也會參與計算

BFC 的應用

自適應多欄佈局

利用 特性③特性④,中間欄建立 BFC,左右欄寬度固定後浮動。因爲盒子的 margin box 的左邊和包含塊 border box 的左邊相接觸,同時浮動盒的區域不會和 BFC 重疊,因此中間欄的寬度會自適應,示例

防止外邊距摺疊

利用 特性②,建立新的 BFC ,讓相鄰的塊級盒位於不一樣 BFC 下能夠防止外邊距摺疊,示例

清除浮動

利用 特性⑤BFC 內部的浮動元素也會參與高度計算,能夠清除 BFC 內部的浮動,示例

寫在最後

本文首發於個人 博客,才疏學淺,不免有錯誤,文章有誤之處還望不吝指正!

若是有疑問或者發現錯誤,能夠在評論區進行提問和勘誤,

若是喜歡或者有所啓發,歡迎 star,對做者也是一種鼓勵。

(完)

相關文章
相關標籤/搜索