margin折叠在布局中经常发生,需要知道margin折叠触发规则和它遵循什么规则计算距离。
margin折叠的规则
- 两个或多个毗邻的普通流中的块元素垂直方向上的margin会折叠
- 浮动元素/inline-block的元素/绝对定位元素的margin不会和垂直方向上的其他元素的margin折叠
- 创建了块级格式化内容的元素,不和它的子元素发生margin折叠
- 元素自身的margin-bottom和margin-top相邻时也会折叠
B
<div style="border:1px solid red; width:100px;">
<div style="margin:50px 0; background-color:green; height:50px; width:50px;">
<div style="margin:20px 0;">
<div style="margin:100px 0;">B</div>
</div>
</div>
</div>
margin collapsing
- 上边距只要不设置border/padding,都会发生重叠.
里面的三个div都发生了重叠
- 下边距只要设置高度,就不会重叠.
例如第二个div设置了高度50px,它的子元素margin-bottom与它不会发生重叠
B
<div style="border:1px solid red; width:100px;">
<div style="margin:50px 0; background-color:green; height:50px; width:50px;">
<div style="margin:20px 0;">
<div style="margin:-60px 0;">B</div>
</div>
</div>
</div>
margin值有正有负
- 若margin有正有负,则取正最大和负最小相加.
-60+50=-10,所以上边距为-10px
- 子元素的margin-top会影响它跟最近的设置了padding或者border的父节点位置.
更改B的margin,相对绿色div的位置不变,相对于设置了border的外层div位置会变化
A
B
<div style="background-color:green;width:50px;margin-top:50px;">
<div style="margin-top:-30px;margin-bottom:30px;">
<div style="margin-top:50px;margin-bottom:-30px;">A</div>
</div>
</div>
<div style="margin:-10px 0; background-color:green; width:50px;">
<div style="margin:-10px 0;">
<div style="margin:40px 0;">B</div>
</div>
</div>
上下两个元素重叠
- 两个相邻的元素之间的距离,是由上一个元素的margin-bottom和下一个元素的margin-top的得出的.
AB两个元素的距离,取位于A元素的有效的margin-bottom(注意height,border对margin-bottom的影响),取B元素的有效的margin-top,在两个元素的数据中取最大正值,和最小负值,两值相加得到就是两个元素的margin距离。
A的有效margin-bottom为30px、-30px,B有效margin-top为-10px、-10px、40px,AB的距离=-30px+40px=10px;
B
<div style="border:1px solid red; width:100px;">
<div style="margin:50px 0; background-color:green; height:50px; width:50px;">
<div style="margin:20px 0;">
<div style="margin:100px 0;">B</div>
</div>
</div>
</div>
创建了BFC元素margin折叠
- 创建了block formatting context元素,就像设置了border和padding一样效果.
什么样的元素会创建bfc,请看http://www.zhoumingzhi.com/2010/06/24/intro-block-formatting-context/
A
B
<div style="margin:10px 0; background-color:green; width:50px;">A</div>
<div style="margin:10px 0; background-color:green; width:50px;float:left;">B
</div>
设置了某些css值的margin折叠
- 元素设置了inline-block、float、position.
设置了这些属性的元素,margin不与内部元素折叠,也不与相邻元素折叠