完整解釋
白話:兩個垂直外距有時會疊成一個,不是永遠相加;flow-root 像替容器建立自己的排版邊界。
正式說法:在 block formatting context 中,特定相鄰 block-level boxes 的垂直 margins 會 collapse;建立新的 BFC 可阻止父子 margin collapse。
何時使用:區塊上下距離與兩個 margin 數值加總不同,或第一個子元素 margin 看似跑到父層外時。
修改前後:Before:看到 24px 與 32px 就宣稱間距是 56px。After:以 rect 差值辨認合併,必要時建立 BFC。
常見混淆:Flex/Grid item 的 margins 不會以相同規則 collapse;gap 也不是 margin collapse。
名詞與最小範例
margin collapse Margin collapsing
- 白話
- 兩個垂直外距有時會疊成一個,不是永遠相加;flow-root 像替容器建立自己的排版邊界。
- 正式定義
- 在 block formatting context 中,特定相鄰 block-level boxes 的垂直 margins 會 collapse;建立新的 BFC 可阻止父子 margin collapse。
- 何時使用
- 區塊上下距離與兩個 margin 數值加總不同,或第一個子元素 margin 看似跑到父層外時。
- 最小範例
- .section { display:flow-root; } .section > h2 { margin-top:2rem; }
- 驗收證據
- runtime before=block、after=flow-root;人工證據記錄父層與 h2 的 rect.top 差值
- 常混淆
- Flex/Grid item 的 margins 不會以相同規則 collapse;gap 也不是 margin collapse。
Micro Lab|margin collapse
情境:區塊第一個 h2 的 margin-top 看似把整個 section 推開,而不是只在 section 內留白。
起始狀態:section 是一般 block,第一個 h2 有 32px margin-top,父層沒有 border/padding。
- 執行實驗替父層切換 establish-bfc,確認 computed display 由 block 變 flow-root,再用 rect 量測父子上緣。
- 執行下方操作,觀察獨立的 DOM 與資料狀態。
- 依證據欄位重新驗收。
目前主題:margin collapse
預期:runtime 的 display 由 block 變 flow-root;人工量測能指出切換前後父子 margin 是否仍穿出容器。
證據:runtime before=block、after=flow-root;人工證據記錄父層與 h2 的 rect.top 差值
第一個檢查:先讀 section 與 h2 的 getBoundingClientRect().top,不先加 padding。
重設:重新載入 module,移除 establish-bfc class。
卡住時
- 症狀:切換 flow-root 後畫面沒有任何差異。
可能原因:父層已有 border/padding、子元素不是第一個 in-flow child,或原本就在 Flex/Grid context。
先檢查:檢查父層 border/padding/display 與子元素 DOM 位置。
修正:恢復最小 fixture:一般 block、無 border/padding、第一個 h2 有 margin-top。
本模組官方來源:MDN|Mastering margin collapsing