原文章链接点击打开链接
晚上没事的时候看看今天白天遗留的问题,果然看的次数再多也不如动动金手,之前也看了很多遍关于外边距折叠的文章,但都没有真正的理解,今天边看边动手,终于理解了,嗯,原作者的文章写得很不错,自己再写估计也是一样只是方式不同,所以就直接转载喽,喜欢的并且英语也不错的可以看原作者的,里面还有英文解释呢
在css中两个或多个盒子(可能是兄弟元素也可能是是父子关系)的相邻边界(期间没有任何非空内容、补白、边框)折叠在一起,而形成一个单一的边界
注意:只有垂直方向的外边距会发生外边距叠加。水平方向的外边距不存在叠加的情况。毗邻说明了他们的位置关系,没有被padding、border、clear和line-box分隔开
两个或多个块级盒子的垂直相邻边界会重合。结果的边界值是相邻边界值中最大的值。如果出现负边界,则在最大的正边界中减去绝对值最大的负边界。如果没有正边界,则从零中减去绝对值最大的负边界。注意:相邻的盒子可能并非是由父子关系或同胞关系的元素生成。
什么时候会发生外边距叠加
外边距叠加存在两种情况:一是父子外边距叠加;二是兄弟外边距叠加。
- 都属于普通流的块级盒子且参与到相同的块级格式上下文中
- 没有被
padding
、border
、clear
和line box
分隔开 - 都属于垂直毗邻盒子边缘:
- 盒子的
top margin
和它第一个普通流子元素的top margin
- 盒子的
bottom margin
和它下一个普通流兄弟的top margin
- 盒子的
bottom margin
和它父元素的bottom margin
- 盒子的
top margin
和bottom margin
,且没有创建一个新的块级格式上下文,且有被计算为0的min-height
,被计算为0或auto
的height
,且没有普通流子元素
- 盒子的
看下面的例子:
.parent1 {
height: 20px;
background: yellow;
margin-bottom: 20px;
}
.parent2 {
margin: 20px 0 30px;
}
.parent3 {
height: 20px;
background: green;
margin-top: 20px;
}
.child {
background: red;
height: 20px;
margin: 40px 0 30px;
}
<div class="parent1"></div>
<div class="parent2">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
<div class="parent3"></div>
这个demo里的.parent2
和第一个.child
的top margin
叠加,导致.parent1
和.parent2
之间的边距为40px
。
demo2:
还是用上面的代码,.parent2
中的.child
中的top margin
和bottom margin
发生外边距叠加,它们之间的外边距为40px
。
demo3:
还是上面的代码,.parent2
中的最后一个.child
发生bottom margin
叠加,.parent2
和.parent3
之间的边距为30px
。
demo4:
.demo {
height: 30px;
background: red;
}
.margin-test {
margin: 20px 0 30px;
}
<div class="container">
<div class="demo"></div>
<div class="margin-test"></div>
<div class="demo"></div>
</div>
这个demo是上面的第四种情况,元素自身的外边距top
和bottom
发生折叠,我们可以看出.container
的高度为90px
,这里可以看到margin-test
的top
和bottom
外边距发生了折叠。
如何避免外边距叠加
上面讲了外边距的叠加,那如何避免呢,其实只要破坏上面讲到的四个条件中的任何一个即可:毗邻
、两个或多个
、普通流
和垂直方向
。
- 浮动元素不会与任何元素发生叠加,也包括它的子元素
- 创建了BFC的元素不会和它的子元素发生外边距叠加
- 绝对定位元素和其他任何元素之间不发生外边距叠加,也包括它的子元素
- inline-block元素和其他任何元素之间不发生外边距叠加,也包括它的子元素
- 普通流中的块级元素的margin-bottom永远和它相邻的下一个块级元素的margin-top叠加,除非相邻的兄弟元素clear
- 普通流中的块级元素(没有border-top、没有padding-top)的margin-top和它的第一个普通流中的子元素(没有clear)发生margin-top叠加
- 普通流中的块级元素(height为auto、min-height为0、没有border-bottom、没有padding-bottom)和它的最后一个普通流中的子元素(没有自身发生margin叠加或clear)发生margin-bottom叠加
- 如果一个元素的min-height为0、没有border、没有padding、高度为0或者auto、不包含子元素,那么它自身的外边距会发生叠加
但是边界的重叠也有例外情况: