先來看看這個例子,你是否也曾經在某個元素加上 top/bottom margin 但卻沒有把上層的 container 撐大,而是 margin 直接穿過了他
這就是神奇的 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
參考資料
以上,可能沒有很完整或很正確,就參考參考吧