文章將陸續整理並更新至個人部落格。
在先前的文章中提到不少次「BFC」,今天就來看看 BFC 是什麼,它又有什麼用處~
摘自 W3C
In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
In a block formatting context, each box's left outer edge touches the left edge of the containing block (for right-to-left formatting, right edges touch).
也就是說,處在同一個 BFC
佈局環境中的元素(盒子),會有以下的佈局現象:
元素從其包含塊(containing block)
的頂部
開始,一個接一個呈現垂直
排列。
若書寫方向
為由左至右
,則元素(盒子)會貼齊包含塊左側
。
兩個元素(盒子)之間的垂直距離
,由元素的 margin
屬性決定。
兩個相鄰(adjacent)的塊級盒子(block-level box)會發生邊距重疊(margin collapsing)
。
需留意的是,對於「什麼時候會建立一個 BFC」,在 W3C level 2.1 規範 與 level 3 規範的定義有些微差異,但在 level 3 規範 有寫到「對於什麼時候會建立 BFC」並沒有一個「非常正式」的定義,有些條件是非常不嚴謹的,其僅列出「可能
」情況。而在 MDN 上則有逐一詳細列出,可供參考。
因 level 3 規範在此處寫得不甚明確,因此以下將採用 2.1 規範的定義,再以 MDN 的定義輔助作為參考。
以下摘自 W3C 2.1 對於 BFC 的定義
Floats, absolutely positioned elements, block containers (such as inline-blocks, table-cells, and table-captions) that are not block boxes, and block boxes with 'overflow' other than 'visible' (except when that value has been propagated to the viewport) establish new block formatting contexts for their contents.
也就是說,下列這些情形會建立
一個新的 BFC
:
float
屬性值不為 none
。
position
值為 absolute
或 fixed
。
為塊容器盒子
(block container box)但不是塊盒子
(block box)的元素。
為塊盒子
(block box),且 overflow
屬性值非 visible
。
註:
① absolutely positioned 是指 position 值為 abosolute 或 fixed。
② 塊容器盒子(block container box) 取決於元素 display 的內部顯示(inner display type),可參考 W3C 的 display 表。
③ 同時為塊級盒子(block-level box) 與塊容器盒子(block container box)的盒子稱為塊盒子(block box)。
另外,一個值得留意的地方是,在 W3C level 3 對於 塊容器(block container) 的定義 中寫到
A block container box can both establish a block formatting context and an inline formatting context simultaneously.
也就是
塊容器盒
(block container box)是可以同時
建立BFC
與IFC
的。
接下來是 MDN 對於何時會建立塊格式化上下文(BFC)的定義。
摘自 MDN
下列方式會創建塊格式化上下文:
- 根元素(<html>)
- 浮動元素(元素的 float 不是 none)
- 絕對定位元素(元素的 position 為 absolute 或 fixed)
- 行內塊元素(元素的 display 為 inline-block)
- 表格單元格(元素的 display 為 table-cell)
- 表格標題(元素的 display 為 table-caption)
- 匿名表格單元格元素(元素的 display 為 table、table-rowtable-row-group、table-header-group、table-footer-groupinline-table)
- overflow 值不為 visible 的塊元素
- display 值為 flow-root 的元素
- contain 值為 layout、content 或 paint 的元素
- flex 元素(display 為 flex 或 inline-flex 元素的直接
子
元素)- grid 元素(display 為 grid 或 inline-grid 元素的直接
子
元素)- 多列容器(column-count 或 column-width 不為 auto 的元素)
- column-span 為 all 的元素始終會創建一個新的 BFC,即使該元素沒有包裹在一個多列容器中。
可以解決:
float
元素的父容器塌陷
問題。外邊距合併
(margin collapsing)問題float 元素會導致外層容器的高度塌陷(若外層容器高度為 auto 且無其它比 float 元素高的子元素)。
<div class="container">
<span>我是裝著 float 盒子的盒子(容器)</span>
<div class="float">我是 float 盒子</div>
</div>
.container {
width: 600px;
background-color: #546E7A;
border: 5px solid #333;
}
.float {
float: left;
width: 200px;
height: 150px;
background-color: #FFAB00;
border:1px solid black;
padding: 10px;
}
此時可以使外層容器建立 BFC 來恢復高度。例如在外層容器加上 overflow: hidden,或 display: flow-root。
當元素與元素之間發生 margin collapsing 時,可透過讓元素建立 BFC,來解決 margin collapsing 問題。
建議先釐清 W3C 規範中常出現的一些關鍵名詞的定義,對於視覺格式化模型的章節會挺有幫助的唷!
例如:
塊格式化上下文(BFC)就此告一段落囉~
掰拉~
此文章為學習筆記,如有錯誤的地方,麻煩告知~感謝!
W3C-Appendix A: Glossary
W3C-Box Layout Modes: the display property
W3C-Collapsing margins
MDN-Block formatting context
MDN-overflow