CSS margin塌陷問題及解決方案
1.????? 什么是margin塌陷問題。
在標準文檔流中,垂直方向的父子元素,當(dāng)給子元素設(shè)置margin-top: 100px時,子元素不會相對父元素頂端距離100個像素,而是父子元素同時相對文檔下移100px?;騽t同時給父子兩個元素設(shè)置margin-top,但是呈現(xiàn)的效果是誰大,父子元素整體像下移動大的距離(此時子元素還是相對父元素不動)。這兩種現(xiàn)象我們都稱作margin塌陷。
表現(xiàn)為較大的margin會覆蓋掉較小的margin,豎直方向的兩個盒子中間只有一個較大的margin,這就是margin塌陷現(xiàn)象
2.????? 我們來看一下margin塌陷的具體現(xiàn)象。如下代碼:

我們上面的代碼本來是想讓son這個div距離parent這個元素的頂部100px,parent這個元素應(yīng)該是距離文檔頂部是0。但是表現(xiàn)出來的卻是父元素距離頂部100像素,子元素距離父元素的頂部是0。這就是我們所說的父子元素的margin塌陷。我們這里給父元素加個margin-top:200px。呈現(xiàn)的效果如下:

按照我們現(xiàn)在代碼的展現(xiàn)形式應(yīng)該是son節(jié)點距離文檔頂部應(yīng)該是300px。parent節(jié)點距離頂部200px。但是最終呈現(xiàn)出來的卻是parent和son節(jié)點都是距離頂部200px。
3.????? 解決方法。
方法一:給父元素加上邊框border:1px silod black;(改變了父元素的結(jié)構(gòu))。代碼和效果如下:

但是加了這個之后,整個父元素可以存放的內(nèi)容空間只有198個像素了。
方案二:給父元素加上絕對定位。position:absolute。效果如下:

方案三:display:inline-block;讓父級同時具有行級屬性和塊級屬性。代碼如下:

?????? 方案四:float:left/right;讓父級產(chǎn)生浮動流。代碼:

方案五:overflow:hiddle;溢出部分隱藏。如下:

4.????? 總結(jié):方案二到方案五的解決方案我們叫做“觸發(fā)盒子的BFC模型”。什么是BFC模型?
其全英文拼寫為 Block Formatting Context 直譯為“塊級格式化上下文”。也就是說只有塊級元素才有這種說法。(非塊級元素,我們也是可以讓它變成塊級元素)BFC具有如下的特性:
1.?? 內(nèi)部的box會在垂直方向,一個接一個的放置
2.?? 每個元素的margin box的左邊,與包含塊border box的左邊相接觸(對于從做往右的格式化,否則相反)
3.?? box垂直方向的距離由margin決定,屬于同一個bfc的兩個相鄰box的margin會發(fā)生重疊
4.?? bfc的區(qū)域不會與浮動區(qū)域的box重疊
5.?? bfc是一個頁面上的獨立的容器,外面的元素不會影響bfc里的元素,反過來,里面的也不會影響外面的
6.?? 計算bfc高度的時候,浮動元素也會參與計算
5.????? 下面我們再來看看margin合并的問題。主要表現(xiàn)在兄弟兩個元素上面。上面一個元素設(shè)置了margin-bottom,下面一個元素設(shè)置了margin-top。但是兩個元素垂直距離并不是兩個margin之和而是取其中一個。具體看下面的代碼:

這兩個元素垂直方向的距離只會在margin-top和margin-bottom兩者取其中一個較大值。這就是我們所說的margin合并現(xiàn)象。
6.????? 解決方案。
1.????? 給son2元素加一個父級元素,并給這個父級元素設(shè)置上面方案二到方案五其中一個。如下:

2.????? 給這兩個子元素都在加個父元素。并給這兩個父元素設(shè)置上面方案二到方案五其中一個。代碼如下:

7.????? 總結(jié)。上面的解決方案都改變了文檔的結(jié)構(gòu)。一般是不建議采用。如果萬一我們確實需要兩個兄弟元素垂直相距這么大的距離,我們只需要給其中一個設(shè)置margin屬性就行了。比如給上一個設(shè)置margin-bottom屬性或者是給下面的元素設(shè)置margin-top屬性。