這一篇來說明一下css當(dāng)中一些bug,這兩個(gè)bug出現(xiàn)在margin屬性上面,分別是margin合并和margin塌陷
margin合并
首先我們理解一下margin的正常效果,比如下面的例子,我們通過margin讓兩個(gè)元素隔開
<span class="left">我在左邊</span>
<span class="right">我在右邊</span>
.left{
color: red;
margin-right: 20px;
}
.right{
color: green;
margin-left: 20px;
}
/* 這樣設(shè)置之后,他們之間的間距應(yīng)該是 20px + 20px = 40px */
當(dāng)然顯示出來的樣子和我們預(yù)期的是一樣的!

那么margin合并出現(xiàn)在什么地方呢?那么我們來看一下上下布局的時(shí)候,這里的margin的情況
<div class="top">我在上面</div>
<div class="bottom">我在下面</div>
.top{
width: 100px;
height: 100px;
background: red;
margin-bottom: 100px;
}
.bottom{
width: 100px;
height: 100px;
background: green;
margin-top: 100px;
}
/*理論上我們看到的應(yīng)該是兩個(gè)div上下相隔200px*/
但是實(shí)際上和我們猜測(cè)的有點(diǎn)出入,它們這里的div的高度是100px

所以什么是margin合并呢?
兄弟結(jié)構(gòu)水平方向的margin正常,但是垂直方向上面的margin會(huì)合并,并且這里的取到的是較大的一個(gè),一般情況下,margin合并我們可以不處理,合理安排垂直方向的margin就能達(dá)到需求效果。
margin塌陷
父子結(jié)構(gòu)的元素,垂直方向上的margin,會(huì)取最大那個(gè)
<div class="box">
<div class="wrapper">
<div class="content"></div>
</div>
</div>
.box{
width: 300px;
height: 300px;
border: 1px solid #ccc;
}
.wrapper {
width: 100px;
height: 100px;
background: #000;
margin-top: 50px;
margin-left: 50px;
}
.content {
margin-left: 100px;
/*margin-top: 100px;*/
width: 50px;
height: 50px;
background: orange;
}
根據(jù)上面代碼,我們先將margin-top給注釋掉,看一下結(jié)果

我們可以看到,我們的黃色方塊根據(jù)黑色方塊向左移動(dòng)了100px,這樣可以理解,很正常,但是當(dāng)我們將注釋的代碼打開的時(shí)候,根據(jù)上面的經(jīng)驗(yàn)我們應(yīng)該看到的是黃色的方塊到了黑色的方塊的對(duì)角線的下方。

顯然這里出現(xiàn)出乎預(yù)料的問題,就是我們的黃色的方塊帶著黑色方塊向下移動(dòng)了50px,當(dāng)然這就是margin塌陷的問題了,感覺我們的黑色的盒子在垂直方向上面好像不能夠作為margin對(duì)應(yīng)的參照物了,好像頭頂是空的,這就是取名margin塌陷的原因。其實(shí)這里的margin的算法是這樣的==他們的兩個(gè)的margin會(huì)根據(jù)較大的一個(gè)取==,也就是父子在水平方向上,誰大聽誰的,而且是相對(duì)有頭頂?shù)脑?
先了解一下BFC
BFC: block format context - 塊級(jí)格式化上下文,每一個(gè)盒子當(dāng)中都有一套正常的渲染規(guī)則,但是我們可以通過一些語法,來觸發(fā)bfc,讓這個(gè)盒子的渲染規(guī)則不一樣! 就是這個(gè)渲染規(guī)則的改變,剛好就解決了margin塌陷的問題,下面是觸發(fā)bfc的語法:
- position: absolute;
- display:inline-block;
- float:left / right
- overflow: hidden;
margin塌陷的解決方案
- 給父級(jí)元素,上面的黑色盒子,加一個(gè)頭頂,直接使用border-top來處理,但是這樣會(huì)帶來更多的問題,多了的border像素影響也是不小的。
- 使用overflow:hidden;來觸發(fā)bfc來解決,overflow:hidden;自己也有自己的含義,
溢出部分隱藏,這個(gè)方法有個(gè)缺點(diǎn)就是,假如我們有使用js來更換子元素的位置的時(shí)候,一旦出了盒子,就不能顯示了 - 其他觸發(fā)bfc的方法
如上的方案我們根據(jù)實(shí)際情況來選擇,比如假如父級(jí)元素剛好就要加邊框,那么我們就剛好可以選擇第一種方法,根據(jù)需求合理的選擇。
使用bfc來處理margin合并,高端一下
其實(shí)我們可以使用bfc來處理margin合并的情況,給兩個(gè)元素或者其中一個(gè)元素加上一個(gè)父級(jí)元素,并讓父級(jí)元素觸發(fā)bfc
<div class="box">
<div class="top"></div>
</div>
<div class="box">
<div class="bottom"></div>
</div>
.box{
overflow: hidden;
}
.top {
width: 100px;
height: 100px;
background-color: red;
margin-bottom: 100px;
}
.bottom {
width: 100px;
height: 100px;
background-color: green;
margin-top: 100px;
}
處理好的結(jié)果:

但是這種方法是不推薦的,主動(dòng)去改變html結(jié)構(gòu)是很不理想的做法?。?!