CSS盒模型中有一個概念叫做外邊距(margin),用來設定物件四邊的外延邊距。但是對於位置上存在邊距相遇(相鄰、包含、自身為空)的元素,有時候會發生垂直方向上的margin合併的情景。
準則
- 外邊距合併指的是,當兩個垂直外邊距相遇時(一定是直接相遇而沒有padding或者border的阻隔),它們將合併形成一個外邊距
- 合併後的外邊距的高度等於兩個發生合併的外邊距的高度中的較大者
- 如果出現負值,分為一正已負、兩個全是負
常見形式
- 兩元素相鄰時
- 兩元素存在包含關係時
注意,此時的合併的邊距指的是外部元素的邊距,而不是兩者相接觸的內部邊距。w3cSchool描述有誤。
- 自身為空元素時(chrome證實不會發生合併)
假設有一個空元素,它有外邊距,但是沒有邊框或填充。在這種情況下,上外邊距與下外邊距就碰到了一起,它們會發生合併
以上是w3cSchool中的描述,經過驗證並不存在。
總結
經過上面例項,現可總結如下:
- 對於兩個相鄰(標籤巢狀屬於同一層級)元素,由於沒有任何阻隔,所以外邊距必定會相遇,相遇時邊距合併遵循誰大以誰為準的原則
- 對於父子巢狀元素,如果任何一者宣告瞭border或者padding,那麼margin被阻隔,便不會發生合併。如果沒有阻隔,那麼他們中的較大的margin值成為父元素的外邊距實際值,而內部子元素針對於父元素的margin值消失
- 對於一個沒有border、padding、content的元素,margin正常,不會發生自身合併
- 只有普通文件流中塊框的垂直外邊距才會發生外邊距合併。行內框、浮動框或絕對定位之間的外邊距不會合並。
意義和影響
如下,是w3cSchool中的描述,但是對應到上面的驗證和總結,其實這是錯誤的。錯在外部元素包裹內部元素時,第一個內部元素的margin值被合併到外部元素的margin中,因此表現出來就像沒有設定margin一樣。
實際表現如下(chrome):
<div class="wrap">
<div class="outer-container">
<p class="paragraph">段落1</p>
<p class="paragraph">段落2</p>
<p class="paragraph">段落3</p>
<p class="paragraph">段落4</p>
</div>
</div>
複製程式碼
.outer-container {
background: red;
}
.paragraph {
width: 100px;
background-color: yellow;
margin: 10px auto;
}
複製程式碼
一定注意:對於巢狀元素,第一個正常文件流的上邊距一定會被父元素吞併當做自己的邊距。就像子元素沒有設定上外邊距一樣。不論巢狀了幾層。