1. 程式人生 > >CSS外邊距摺疊

CSS外邊距摺疊

外邊距摺疊

Collapsing margins,即外邊距摺疊,指的是毗鄰的兩個或多個外邊距 (margin) 會合併成一個外邊距。

其中所說的 margin 毗鄰,可以歸結為以下兩點:

  • 這兩個或多個外邊距沒有被非空內容、padding、border 或 clear 分隔開
  • 這些 margin 都處於普通流中。

兩個或多個:說明其數量必須是大於一個,又說明,摺疊是元素與元素間相互的行為,不存在 A 和 B 摺疊,B 沒有和 A 摺疊的現象。

毗鄰:是指沒有被非空內容、padding、border 或 clear 分隔開,說明其位置關係。

注意:在沒有被分隔開的情況下,一個元素的 margin-top 會和它普通流中的第一個子元素(非浮動元素等)的 margin-top 相鄰,這時這時子元素的位置和父元素不會隔離,給父元素加padding border 或overflow-hidden可解決;
只有在一個元素的 height 是 “auto”

的情況下,它的 margin-bottom 才會和它普通流中的最後一個子元素(非浮動元素等)的 margin-bottom 相鄰。

示例程式碼:

複製程式碼
<div style="border:1px solid red; width:100px;">
    <div style="margin:50px 0;  height:50px; width:50px;">
       <div style="margin:20px 0;">
           <div style="margin:100px 0;">B</div>
       </div>
</div> </div>
複製程式碼

效果圖:

以上程式碼中,margin 會把 B 的包含塊撐開。

如果一個元素的 height 特性的值不是 auto,那麼它的 margin-bottom 和它子元素的 margin-bottom 不算相鄰,因此,不會發生摺疊。 margin-top 沒有此限制,所以是 100px,margin-bottom 沒有摺疊,只有 50px。

垂直方向

是指具體的方位,只有垂直方向的 margin 才會摺疊,也就是說,水平方向的 margin 不會發生摺疊的現象。

摺疊後 margin 的計算

1). 參與摺疊的 margin 都是正值

例子:

<
div style="height:50px; margin-bottom:50px; width:50px; ">A</div> <div style="height:50px; margin-top:100px; width:50px; ">B</div>

示意圖:
![這裡寫圖片描述](https://img-blog.csdn.net/20161203140715602)

在 margin 都是正數的情況下,取其中 margin 較大的值為最終 margin 值。

2). 參與摺疊的 margin 都是負值

當 margin 都是負值的時候,取的是其中絕對值較大的,然後,從 0 位置,負向位移。

示例程式碼:

<div style="height:100px; margin-bottom:-75px; width:100px; ">A</div>
<div style="height:100px; margin-top:-50px; margin-left:50px; width:100px; ">B</div>

示意圖:
![這裡寫圖片描述](https://img-blog.csdn.net/20161203140654198)

3). 參與摺疊的 margin 中有正值,有負值

如果,毗鄰的 margin 中有正值,同時存在負值會怎樣呢?有正有負,先取出負 margin 中絕對值中最大的,然後,和正 margin 值中最大的 margin 相加。

示例程式碼:

<div style="height:50px; margin-bottom:-50px; width:50px; ">A</div>
<div style="height:50px; margin-top:100px; width:50px; ">B</div>

示意圖:
![這裡寫圖片描述](https://img-blog.csdn.net/20161203140628305)

上面的例子最終的 margin 應該是 100 + (-50) = 50px。

4). 相鄰的 margin 要一起參與計算,不得分步計算

要注意,相鄰的元素不一定非要是兄弟節點,父子節點也可以,即使不是兄弟父子節點也可以相鄰。

而且,在計算時,相鄰的 margin 要一起參與計算,不得分步計算。

一個複雜的例項:

複製程式碼
<div style="margin:50px 0;  width:50px;">
    <div style="margin:-60px 0;">
           <div style="margin:150px 0;">A</div>
    </div>
</div>
<div style="margin:-100px 0;  width:50px;">
    <div style="margin:-120px 0;">
           <div style="margin:200px 0;">B</div>
    </div>
</div>
複製程式碼

錯誤的計算方式:算 A 和 B 之間的 margin,分別算 A 和其父元素的摺疊,然後與其父元素的父元素的摺疊,這個值算出來之後,應該是 90px。依此法算出 B 的為 80px;然後,A和B摺疊,margin 為 90px。

請注意,多個 margin 相鄰摺疊成一個 margin,所以計算的時候,應該取所有相關的值一起計算,而不能分開分步來算。

以上例子中,A 和 B 之間的 margin 摺疊產生的 margin,是6個相鄰 margin 摺疊的結果。將其 margin 值分為兩組:

  • 正值:50px,150px,200px
  • 負值:-60px,-100px,-120px

根據有正有負時的計算規則,正值的最大值為 200px,負值中絕對值最大的是 -120px,所以,最終摺疊後的 margin 應該是 200 + (-120) = 80px。

5).浮動元素、inline-block 元素、絕對定位元素的 margin 不會和垂直方向上其他元素的 margin 摺疊

浮動元素的 margin 在垂直方向上也不會發生 margin 摺疊,即使和它相鄰的子元素也不會。

<div style="margin-bottom:50px; width:50px; height:50px; ">A</div>
<div style="margin-top:50px; width:100px; height:100px;  float:left;">
    <div style="margin-top:50px; ">B</div>
</div>

示意圖:
![這裡寫圖片描述](https://img-blog.csdn.net/20161203140556133)

兩個綠色的塊兒之間,相距100px,而若 B 和它的浮動包含塊發生 margin 摺疊的話,金色的條應該位於綠色塊的最上方,顯然,沒有發生摺疊。

6).建立了塊級格式化上下文的元素,不和它的子元素髮生 margin 摺疊

以 “overflow : hidden” 的元素為例:

<div style="margin-top:50px; width:100px; height:100px;  overflow:hidden;">
    <div style="margin-top:50px; ">B</div>
</div>

若 B 和它的 “overflow:hidden” 包含塊發生 margin 摺疊的話,金色的條應該位於綠色塊的最上方,否則,沒有發生。

示意圖:
![這裡寫圖片描述](https://img-blog.csdn.net/20161203140508211)

7).元素自身的 margin-bottom 和 margin-top 相鄰時也會摺疊

自身 margin-bottom 和 margin-top 相鄰,只能是自身內容為空,垂直方向上 border、padding 為 0。

示例:

<div style="border:1px solid red; width:100px;">
    <div style="margin-top: 100px;margin-bottom: 50px;"></div>
</div>

以上程式碼執行後,我們講得到的是紅色邊框的正方形,方框的寬高都應該是 100px,高度不應該是 150px。

示意圖:
無