[CSS] margin 排版問題(Collapsing margins)
Contents
CSS 的 Margin Collapsing(外距合併)是一個讓初學者感到困惑的排版機制:在某些情況下,兩個垂直方向的 margin 不會相加,而是合併(collapse)成較大的那個值。
Margin Collapsing 的三種情況
1. 相鄰兄弟元素(Adjacent Siblings)
兩個緊鄰的區塊元素,上方元素的 margin-bottom 和下方元素的 margin-top 會合併:
|
|
實際間距不是 20 + 30 = 50px,而是取較大值 30px。
2. 父子元素(Parent and First/Last Child)
當父元素和第一個子元素之間沒有 border、padding、BFC 阻隔時,子元素的 margin 會「穿透」到父元素外:
|
|
結果:parent 和 child 的 margin-top 合併為 30px,這個 margin 作用在父元素上,而非子元素相對於父元素內部。
3. 空的區塊元素(Empty Block)
一個沒有 border、padding、content 的空元素,自身的 margin-top 和 margin-bottom 會合併:
|
|
為什麼 inline-block 和 Flex 不會 Collapse?
inline-block 不會發生 Collapsing
inline-block 元素是行內格式化上下文(IFC)的一部分,而 margin collapsing 只發生在區塊格式化上下文(BFC)中的區塊元素之間。
|
|
Flex 容器不會發生 Collapsing
Flex 容器會為其子元素建立新的 BFC,因此 flex 子項目之間不會發生 margin collapsing:
|
|
重要規則
- Margin collapsing 只發生在垂直方向(上下),水平方向的 margin(左右)永遠不會合併
block元素只有上下 margin 會受影響,左右不受影響- 合併後的 margin 值 = 兩個值中較大的那個(若有負值則另有計算規則)
如何防止 Margin Collapsing
方法一:使用 overflow: hidden 建立 BFC
|
|
方法二:加入 padding 或 border
|
|
方法三:使用 Flexbox 或 Grid
|
|
方法四:使用 display: flow-root
|
|