深入CSS之外邊距折疊(margin collapse)詳解

什么是外邊距折疊

準確來說,外邊距折疊應該叫垂直外邊距折疊,因為只會發生在垂直方向上,而水平方向上不會發生。

對于以下簡單的html代碼和css代碼, 請問top塊和bottom塊之間的垂直間距是多少px?

<div class="container">
  <div class="block top"></div>
  <div class="block bottom"></div>
</div>
.block {
  width: 100px;
  height: 100px;
  background-color: lightgray;
}
.top {
  margin-bottom: 20px;
}

.bottom {
  margin-top: 30px;
}

如果你不了解外邊距折疊,那么你會認為:
間距 = top塊的margin-bottom + bottom塊的margin-top
  =20px + 30px = 50px

然而實際情況是:


image.png
image.png

這就是(垂直)外邊距折疊。

外邊距折疊的定義:
The top and bottom margins of blocks are sometimes combined (collapsed) into a single margin whose size is the largest of the individual margins (or just one of them, if they are equal), a behavior known as margin collapsing. Note that the margins of floating and absolutely positioned elements never collapse.
翻譯過來就是:
塊級元素的上下外邊距(margin)在某些情況下會合并(折疊)起來,合并之后的大小為較大的margin。注意浮動和絕對定位的元素的margin從不折疊。

發生外邊距折疊的條件是什么

  1. (垂直方向上)相鄰的兩個元素
    這種情況很好理解,就是上面的例子中給出的情況。這里要注意一點,所謂相鄰指的是渲染之后的元素位置相鄰,而不是dom結構上的相鄰,也就是說如果將代碼:
<div class="container">
  <div class="block top"></div>
  <div class="block bottom"></div>
</div>

改成

<div class="container">
  <div>
    <div class="block top"></div>
  </div>
  <div class="block bottom"></div>
</div>

雖然加了一層div包裹,但是仍然會發生外邊距折疊。

  1. 父元素和第一個/最后一個子元素之間
    考慮以下代碼:
<div class="parent">
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
  <div class="child"></div>
</div>
.parent {
  margin-top: 30px;
}

.child {
  margin-top: 20px;
  width: 50px;
  height: 50px;
  background-color: lightgray;
}

parent塊有margin-top: 30px;child塊有margin-top: 20px;,那么第一個子元素距離最上面的距離是50px嗎?不是,由于有外邊距折疊的存在,折疊后的距離為30px。

image.png
image.png

外邊距折疊后的大小

1.兩個相同大小的正數:取某個外邊距的值。即30px與30px發生折疊,折疊后的值為30px。
2.兩個不同大小的正數:取較大的外邊距的值。即30px與20px發生折疊,折疊后的值為30px。
3.一正一負:取正數與負數的和。即30px與-20px發生折疊,折疊后的值為10px。
4.相同大小的負數:同相同大小正數。-30px與-30px折疊,折疊后為-30px。
5.不同大小負數: 取絕對值較大的負數。-30px與-20px折疊,折疊后為-30px。

如果我希望不發生外邊距折疊,該怎么做

1.曲線救國,如果你希望垂直方向上兩個塊間距為50px,可以通過設置上方塊margin-bottom: 50px;而非采用30px + 20px;來實現。
2.根據BFC(block formatting context)塊級格式化上下文來阻止外邊距折疊。你可以試著將本文給出的第一個例子中的top塊設置:display: inline-block;來形成BFC。這樣就不會再發生外邊距折疊了。我在實驗中發現,在設置了display:inline-block之后,期望的間距為50px,但是實際情況如下:

image.png
image.png

發現竟然是54px,那么多出來的4px是哪來的?該如何處理掉多余的4px?這里先不做解釋,留個坑,在另一篇文章《inline-block產生的看不見的空間》里解釋。至于如何處理,只需要在container上加上font-size: 0;即可,就會得到我們想要的50px。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容