iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 9
3
自我挑戰組

每天來點 CSS Specification系列 第 9

話說 Margin-collapse 是什麼呢?

倘若不斷向深處扎根,就能茁壯成長 - RM

/images/emoticon/emoticon07.gif

前言

今天我們要聊到的是邊距重疊 Margin-collapse,會延續參考 CSS 2.2 Box model 的內容,原因同樣是因為 Level 3 位於草案階段,除此之外,Margin-collapse 在 Level 3 中也沒有詳述,Level 3 規範建議參考 CSS2.2 目前的內容(見下圖),那我們開始吧~

https://ithelp.ithome.com.tw/upload/images/20190924/20111825r7hACRWImw.png

Margin-collapse

規範直通車:Box model
請參考 8.3.1 Collapsing margins

規範定義
In CSS, the adjoining margins of two or more boxes (which might or might not be siblings) can combine to form a single margin. Margins that combine this way are said tocollapse, and the resulting combined margin is called acollapsed margin.
指的是 boxes 邊距在某些情況下,會合併成單一個,稱為邊距重疊現象。

今天要提到的 Margin-collapse 相信大家可能都有遇見過,中文叫做邊距重疊,也就是指在某些情況下 Margin 會重疊的現象,那是什麼意思呢?比如就像我今天設定了父子元素皆為 <div>,然後對子元素下了 margin: 100px
Codepen直通車

.container{
  width: 500px;
  height: 500px;
  background-color: lightblue;
}
.item{
  width: 50px;
  height: 50px;
  margin: 100px;
  background-color: tomato;
}

產生的結果是這樣子的,可以看見子元素的 margin-top 跑出去了,這是 Margin-collapse 造成的現象。
https://ithelp.ithome.com.tw/upload/images/20190924/201118251FAy4My79h.png

其實在許多情況下,Margin-collapse 會讓我們需要做出許多調整,也有許多人對於這個現象感到怪異,但是若是對它有了足夠的了解,會更容易解決遇到它所產生的現象,像是 Andrew Grant in 2015 就有說到這段話:

It's probably not the most intuitive aspect of CSS, but the takeaway here is that there is some logic at play and, once you have learned it, the mystery and confusion suddenly disappears!

他說到瞭解 Margin-collapse 會讓我們更好的去解決 Margin-collapse 產生的問題,不過對於 <p><h1><h2> ... 等標題段落時合併它的距離時還是有優點的,會保持文字段落距離取大值。Codepen範例

/images/emoticon/emoticon12.gif

Margin-collapse 發生的時機

Margin-collapse 需要滿足某些條件才會觸發,那麼在什麼樣的情況下會觸發呢,以下整理出會發生的時機和需要滿足的條件:

  • Margin-collapse 水平方向無此情況。
  • root 元素不會 Margin-collapse。
  • 當兩個皆是 block in-flow 狀態且參與相同的 BFC 時。(BFC 日後會提到,先看過即可。)
  • 兩個 block 沒有 paddingborder 、line box、clearance 隔開時。
  • 當符合以下幾種垂直 edge 重疊情況時:
    • 父元素和第一個子元素的 margin-top
    • 父元素和最後一個子元素的 margin-bottom,且父元素高度需要是 auto 狀態
    • 兄弟元素的上下 margin
    • 當一個 box 的高為 auto、mix-height 為 0,且沒有 in-flow 子代時。(範例:collapse-box

以下的狀態不會發生 Margin-collapse:

  • float 元素兄弟、父子(no in-flow 、產生新 BFC)
  • 絕對定位元素兄弟、父子(no in-flow 、產生新 BFC)

如何解決 Margin-collapse

當遇到會產生 Margin-collapse 時,剛剛也有提到若是在段落與標題之間的距離或許是一個優點,但在這個情況之外產生 Margin-collapse 時,我們可以如何避免這個問題呢?以下列出其中幾種方法...

  • 使用 padding 解決,不要使用 margin - 建議使用
  • 設定 border (兄弟時不管用),會作用的原因是因為 independent formatting context

https://ithelp.ithome.com.tw/upload/images/20190924/201118259RbPgm460F.png

  • 將元素轉為非 in-flow 狀態如,float 或是絕對定位 - 不建議使用
  • overflow: visible 屬性值以外 - 不建議使用

通常我習慣的避免邊距重疊的方式偏向改以 padding 設定,避免掉 Margin-collapse 的同時也不要去產生新的 BFC,保有它原本的狀態。

結語

今天我們聊到了 Margin-collapse ,對於其中的狀態作出了一些解釋,我們平時也可以透過一些其他的方法去嘗試避免掉 Margin-collapse,不過如同文中敘述,在某些狀態下 Margin-collapse 有它的優點存在,我們明天見啦~

/images/emoticon/emoticon42.gif


參考資料

  1. Box model
  2. CSS Box Model Module Level 3
  3. https://www.w3.org/TR/CSS2/box.html#collapsing-margins

以上的部分有任何錯誤的地方,歡迎指正呦~非常感謝~~XD


上一篇
話說 Box model 是什麼呢?
下一篇
在看 Visual Formatting Model 之前,先說些別的~
系列文
每天來點 CSS Specification30

尚未有邦友留言

立即登入留言