筆記一下 CSS collapsing margins 重疊問題

原來是鬼打牆,還以為是重疊呢

YY
5 min readDec 30, 2020
https://css-tricks.com/css-is-awesome/

最近剛好看到跟 collapsing margins 有關的文章,突然喚醒了一些藏在內心深處不敢觸碰的記憶,也是第一次知道原來有這麼一個詞而且是 CSS 規格的一部份(我就爛

先來看看這個例子,你是否也曾經在某個元素加上 top/bottom margin 但卻沒有把上層的 container 撐大,而是 margin 直接穿過了他

margin 居然沒辦法把 container 撐高?!

這就是神奇的 collapsing margins 啦

但這規則說起來也是有點複雜,以下就概略記錄一下常見的幾個特性讓下次鬼打牆的時候可以參考,如果有興趣的話也可以去了解更多細節:

沒被分隔的 parent’s & descendants’ margins

當 parent 的 margin-top/bottom 與任一 descendants 的 margin-top/bottom 中間沒有被阻隔的話就會 collapse

可以看到上面這個 codepen 中有一個 container 包了三層 div,且各自都有不同的 margin-top,最後都與 parent 也就是 container (實際上應該是 body) 的 margin collapse

關於何謂 margin 被阻隔,即是兩者間出現了 border、padding、inline 元素、建立新的 block formatting context 等都會阻止 parent、descendants 的 margins collapse

而下列這些情況會產生新的 block formatting context

  • <html>
  • position 為 absolute fixed
  • float
  • inline-block
  • overflow 值不為 visible clip

更多可參考 MDN

簡單來說,當你遇到這種 margin 超出 container 的狀況時,本質上是你對 CSS 的誤用,但你可以試試在 container 加上overflow: auto ,或其實你需要的是 padding

相鄰兩 block 的 margin

在同個 block formatting context 中兩相鄰的 block 之 margin-bottom 與 margin-top 會 collapse

如上,兩個相鄰的 div 皆有 50 px 的上下 margin,但 item1 的 margin-bottom 與 item2 的 margin-top 發生 collapse,所以兩者間隔是 50px 而非 100px

Empty block

對於一個沒有 border、padding、inline content、height、min-height 的 block,其 margin-top 與 margin-bottom 會 collapse

如上方 container 中有一個空的 div 並設定 margin top & bottom 為 50px,而實際呈現出的 margin 大小為 50px 而非 100px

大就是一切

當兩個或多個 margin 發生 collapse 時,最終所呈現的 margin 大小為最大者

當兩個 margin 都為負值時,取絕對值大者

而 margin 為一正一負則會相互抵銷

垂直方向的相鄰 margin 才會 collapse

一般來說就是 margin-top 與 margin-bottom,或是 writing-mode 為 vertical 時的左右 margin

以上,可能沒有很完整或很正確,就參考參考吧

--

--