1. 程式人生 > >margin的摺疊與計算以及解決之道

margin的摺疊與計算以及解決之道

今天就來捋一捋簡單低調卻奢華的css,主要魯三個點:

一.margin的摺疊

二.margin摺疊後的計算

三.margin摺疊的解決之道

先來捋一捋margin的摺疊:

主要分為父子摺疊以及兄弟摺疊,都是垂直方向上的摺疊

父子摺疊(不一定是父子,可以是多層級的包含,只要是空盒子巢狀)看例子:

<ul style="margin-top:2px>

<li style="margin:10px 0"></li>

<li style="margin:10px 0"></li>

<li style="margin:10px 0"></li>

<li style="margin:10px 0"></li>

<li style="margin:10px 0"></li>

</ul>

我們的目的是想讓li和ul之間有個10px的間隔:但是現實是殘酷的,發現不管是ul的頂部還是底部,都沒有和li間隔開,反而是ul和上面的元素還有下面的元素間隔開了10px,

我X,什麼鬼,居然連乾坤大挪移都用上了?客官別急,其實是因為ul和li的垂直margin摺疊了,所以最後就程式設計只有ul有margin,而且是10px,為什麼是10px?怎麼解決?

別急,摺疊計算和解決之道在後面會詳細解答,客官只要記住,兩個巢狀的盒子中間沒有非空內容間隔,它們垂直的margin會合並。這就是巢狀盒子的margin摺疊

我咋一看,不對啊,li之間應該是20px的間隔才是的,怎麼只有10px呢?那是因為li發生了另一種margin摺疊,兄弟摺疊

出發條件,當兩個普通流元素(非浮動非定位)的margin也會摺疊,比如第一個li的margin-bottom和第二個的margin-top會摺疊,所以最後就只會取其中一個,這就是兄弟margin摺疊,到此,摺疊產生就講完了,立馬進入第二個主題:

二.摺疊的計算

2.1  參加摺疊的margin都是正值:取其中 margin 較大的值為最終 margin 值。

2.2 參與摺疊的 margin 都是負值:取的是其中絕對值較大的,然後,從 0 位置,負向位移。

2.3 參與摺疊的 margin 中有正值,有負值:先取出負 margin 中絕對值中最大的,然後,和正 margin 值中最大的 margin 相加。

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

<div style="margin:50px 0; background-color:green; width:50px;">
    <div style="margin:-60px 0;">
           <div style="margin:150px 0;">A</div>
    </div>
</div>
<div style="margin:-100px 0; background-color:green; 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。

margin摺疊計算就講完了,接下來講講解決之道:

三.解決margin摺疊

3.1巢狀margin摺疊型別解決方法

1.在父層盒子新增:overflow:hidden (比較暴力,如果有懸浮窗可能導致無法看到)

2.不用margin-top,改用padding-top (如果子盒子有border,那這個方法就不適合了)

3.給父元素新增1px的padding或者新增一個style不為none的border,可以使用透明border(如果設計師不能容忍1px的差異,那這個就不適用了)

4.給父元素加上浮動(如果要佔滿一行那就要加上width:100%)

5.設定父元素dispaly:inline-block或者display:table-cell;(如果要佔滿一行那就要加上width:100%)

6.給父元素新增絕對定位(不推薦)

這幾個方法都能解決巢狀導致的margin摺疊問題,任君選擇

3.2 兄弟之間的margin摺疊解決方法

1.給最後面的兄弟加上浮動

2.給最後面的元素加上display:inline-block;

各位客官,今天就捋到這,下回再見