margin重叠的特性
- 只发生在block水平的元素(不包含float和absolute的元素)
- 不考虑writing-mode,只发生在垂直方向(margin-top,margin-bottom)
margin重叠发生的三种情景
- 相邻的兄弟元素之间发生margin重叠
- 父级和第一个或最后一个子元素之间发生margin重叠
- 空的block元素,自己同自己发生margin重叠
1. 相邻的兄弟元素
p{
line-height: 2em;
margin: 1em 0;
background-color: #999;
}
<p>第一行</p>
<p>第一行</p>
理想情况下两个p标签之间距离应该有2em,(第一行的margin-bottom + 第二行的margin-top),而此处两个p标签之间距离只有1em,发生margin重叠
2. 父级和第一个/最后一个子元素
.father{
background-color: #aaa;
}
.son{
margin-top:80px;
}
<div class="father">
<div class="son">I'm son.</div>
</div>
理想情况下margin-top区域的颜色应该为father的背景色,而此处颜色并非#aaa 发生margin重叠
再来看更有意思的
<div class="father" style="margin-top: 80px">
<div class="son" style="margin-top: 80px">I'm son.</div>
</div>
<div class="father" style="margin-top: 80px">
<div class="son">I'm son.</div>
</div>
以上三段代码效果居然完全一致,除了第三个效果如我们所想,另外两个都发生了margin重叠
消除父子margin重叠
margin-top重叠
- 父元素为块状格式化上下文元素BFC
<div class="father" style="overflow: hidden;"> <div class="son" style="margin-top: 80px">I'm son.</div> </div> - 父元素有border-top设置
<div class="father" style="border-top: 2px solid #000"> <div class="son" style="margin-top: 80px">I'm son.</div> </div> - 父元素有padding-top设置
<div class="father" style="padding-top: 20px"> <div class="son" style="margin-top: 80px">I'm son.</div> </div> - 父元素和第一个子元素之间有inline元素隔开
<div class="father"> <div class="son" style="margin-top: 80px">I'm son.</div> </div>
margin-bottom重叠
- 父元素为块状格式化上下文元素BFC
- 父元素有border-bottom设置
- 父元素有padding-bottom设置
- 父元素和最后一个子元素之间有inline元素隔开
以上四种处理方式同margin-top的处理方式一致
-
父元素有height,min-height,max-height设置
<div class="father"> <div class="son" style="margin-bottom: 80px">I'm son.</div> </div>加上height相关设置
<div class="father" style="height: 60px"> <div class="son" style="margin-bottom: 80px">I'm son.</div> </div> 若设置margin-bottom后超出father的高度范围则无效,不会影响后面的盒子布局<div class="father"style="height: 60px"> <div class="son" style="margin-bottom: 80px">I'm son.</div> </div> <div style="height: 20px; background-color:#000"></div>
3. 空的block元素
<div class="father" style="background-color: #aaa; overflow: hidden;">
<div class="son" style="margin: 80px 0; "></div>
</div>
理想情况下father的高度应为80+80=160,而此处只有80px,发生margin重叠
消除空block元素margin重叠
-
元素有border设置
<div class="father" style="background-color: #aaa; overflow: hidden;"> <div class="son" style="margin: 80px 0; border:1px solid #000"></div> </div> -
元素有padding设置
<div class="father" style="background-color: #aaa; overflow: hidden;"> <div class="son" style="margin: 80px 0; padding:20px"></div> </div> -
元素里有inline元素
<div class="father" style="background-color: #aaa; overflow: hidden;"> <div class="son" style="margin: 80px 0;"> </div> </div> -
有height或min-height设置
<div class="father" style="background-color: #aaa; overflow: hidden;"> <div class="son" style="margin: 80px 0; min-height: 20px"></div> </div>
margin重叠的意义
- 连续段落或者列表之类,如果没有margin重叠的话,首尾项间距会和其他兄弟标签1:2关系,排版不自然。
- web中任何地方嵌套或者直接放入裸div,不会影响原来的布局。
- 遗落的任意多个空p标签,不要影响原来的阅读排版。
善用margin
做列表的时候,虽然只设置margin-top也可以达到布局的目的
.list {
margin-top: 20px;
}
但是为了健壮性,可以设置margin-top和margin-bottom,虽然会发生margin重叠,但当假如最后一个元素被移除或者位置被置换了,都不会破坏原来的布局样式。
.list {
margin-top: 20px;
margin-bottom:20px;
}