什么是外邊距折疊
準確來說,外邊距折疊應該叫垂直外邊距折疊,因為只會發生在垂直方向上,而水平方向上不會發生。
對于以下簡單的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
然而實際情況是:
這就是(垂直)外邊距折疊。
外邊距折疊的定義:
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從不折疊。
發生外邊距折疊的條件是什么
- (垂直方向上)相鄰的兩個元素
這種情況很好理解,就是上面的例子中給出的情況。這里要注意一點,所謂相鄰指的是渲染之后的元素位置相鄰,而不是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包裹,但是仍然會發生外邊距折疊。
- 父元素和第一個/最后一個子元素之間
考慮以下代碼:
<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。
外邊距折疊后的大小
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,但是實際情況如下:
發現竟然是54px,那么多出來的4px是哪來的?該如何處理掉多余的4px?這里先不做解釋,留個坑,在另一篇文章《inline-block產生的看不見的空間》里解釋。至于如何處理,只需要在container上加上font-size: 0;即可,就會得到我們想要的50px。