CSS 原理 - Block Formatting Context

CSS 原理 - Block Formatting Context

或許你沒聽過 Block Formatting Context,但你肯定有用過!其實在切版時,常常會使用到 BFC,只是你沒有意識到而已,如果能夠有意識的使用 BFC,對於版面的掌控非常有幫助。


什麼是 Block Formatting Context

如同上一篇 CSS 原理 - Formatting Context 所說,Formatting Context 指的是佈局環境,而佈局環境有許多種,不同的佈局環境會有不同的佈局規則,Block Formatting Context (BFC)是其中一種。

下方為一段 W3C 對於 BFC 的敘述:

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(包含塊)的頂部開始,一個接一個呈現垂直排列。

  • 若書寫方向為預設的由左至右,則元素(盒子)會貼齊其 containing block(包含塊)左側。

  • 相鄰元素(盒子)之間的垂直距離,由元素的 margin 屬性決定。

  • 相鄰的 block-level box(塊級盒子)垂直方向會發生 margin collapsing(邊距重疊)


圖示

將上述現象用圖形表示:

1
2
3
4
5
6
7
<html>
<body>
<div></div>
<div></div>
<div></div>
</body>
</html>

首先,<html> 會建立一個 BFC (先破梗了),而 <body> 與三個 <div> 參與的是 <html> 建立的 BFC,也就是說, <body> 與三個 <div> 處於同一個 BFC 中,因此元素會:

  • 呈現垂直排列。
  • 可以用 margin 來推開彼此。
  • 垂直方向會發生 margin collapsing(邊距重疊),其中 margin collapsing 又分為兩種(同層元素間以及元素與其容器間),可參考先前文章 CSS 原理 - Collapsing margins


注意,以上現象強調的是處於同一個 BFC 裡的元素(盒子),若元素自立門戶創建新的 BFC,則不完全適用,所以了解什麼情況會建立新的 BFC 很重要



何時會建立 BFC

對於「什麼時候會建立一個 BFC」,其實 W3C 並沒有一個非常正式的定義,有些條件是非常不嚴謹的,而在 MDN 上則有逐一詳細列出,可供參考。


根據 MDN,以下情況的元素會創建 Block Formatting Context(BFC):

  • <html>
  • float 元素
  • position: absolute、fixed 的元素
  • overflow: hidden、scroll、auto 的元素
  • display: inline-block 的元素
  • display: flow-root 的元素
  • display: flex 或 inline-flex 元素的直接子元素,即 flex items
  • display: grid 或 inline-grid 元素的直接子元素,即 grid items
  • display: table、table-caption、table-cell、table-rowtable-row-group、table-header-group、table-footer-groupinline-table
  • contain: layout、content 或 paint 的元素
  • column-count 或 column-width 不為 auto 的元素
  • column-span 為 all 的元素



BFC 功用

可以解決:

  • float 元素的外層容器塌陷問題。
  • 元素間的 margin collapsing(外邊距重疊)問題
  • float 元素與其他元素的重疊問題 (float 元素遮住其他元素)。

解決 float 元素造成外容器塌陷問題

float 元素會導致外層容器的高度塌陷(若外層容器高度為 auto 且無其它比 float 元素高的子元素)。

例如:範例連結

1
2
3
4
<div class="container">
<span>我是裝著 float 元素的容器</span>
<div class="float">我是 float 元素</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
.container {
width: 600px;
background-color: grey;
border: 5px solid #333;
}

.float {
float: left;
width: 200px;
height: 150px;
background-color: yellow;
border:1px solid black;
padding: 10px;
}


此時可以使外層容器建立 BFC 來恢復高度,例如在外層容器加上 overflow: hidden 或 display: flow-root。

1
2
3
.container{
display: flow-root;
}

登愣~外層容器撐開了。


解決 margin collapsing 問題

當元素與元素之間發生 margin collapsing 時,可使元素建立 BFC 來解決 margin collapsing 的問題。


解決 float 元素遮住其他元素的問題

在先前文章 CSS 原理 - Line box 曾提到,float 元素會擠壓 line box,除此之外,float 元素還可能遮住其它元素!

如果你有用過 float,應該有遇過 float 元素遮住其它非 float 元素的情況,例如:

1
2
<div class="float"></div>
<div class="box"></div>
1
2
3
4
5
6
7
8
9
10
11
12
13
.float{
float: left;
width: 200px;
height: 200px;
background-color: orange;
}

.box{
display: block;
width: 300px;
height: 300px;
background-color: yellow;
}

橘色的 float 元素蓋住了黃色元素。


只要讓黃色元素建立 BFC 即可解決重疊問題,例如加上 overflow: hidden 或 display: flow-root。

1
2
3
.box{
display: flow-root;
}




參考資源

W3C-Appendix A: Glossary
W3C-Box Layout Modes: the display property
W3C-Collapsing margins
MDN-Block formatting context

評論

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×