css中外边距折叠原理及解决办法

原文章链接点击打开链接

晚上没事的时候看看今天白天遗留的问题,果然看的次数再多也不如动动金手,之前也看了很多遍关于外边距折叠的文章,但都没有真正的理解,今天边看边动手,终于理解了,嗯,原作者的文章写得很不错,自己再写估计也是一样只是方式不同,所以就直接转载喽,喜欢的并且英语也不错的可以看原作者的,里面还有英文解释呢

在css中两个或多个盒子(可能是兄弟元素也可能是是父子关系)的相邻边界(期间没有任何非空内容、补白、边框)折叠在一起,而形成一个单一的边界

注意:只有垂直方向的外边距会发生外边距叠加。水平方向的外边距不存在叠加的情况。毗邻说明了他们的位置关系,没有被padding、border、clear和line-box分隔开


两个或多个块级盒子的垂直相邻边界会重合。结果的边界值是相邻边界值中最大的值。如果出现负边界,则在最大的正边界中减去绝对值最大的负边界。如果没有正边界,则从零中减去绝对值最大的负边界。注意:相邻的盒子可能并非是由父子关系或同胞关系的元素生成。

什么时候会发生外边距叠加

外边距叠加存在两种情况:一是父子外边距叠加;二是兄弟外边距叠加。

  • 都属于普通流的块级盒子且参与到相同的块级格式上下文中
  • 没有被paddingborderclearline box分隔开
  • 都属于垂直毗邻盒子边缘:
    • 盒子的top margin和它第一个普通流子元素的top margin
    • 盒子的bottom margin和它下一个普通流兄弟的top margin
    • 盒子的bottom margin和它父元素的bottom margin
    • 盒子的top marginbottom margin,且没有创建一个新的块级格式上下文,且有被计算为0的min-height,被计算为0或autoheight,且没有普通流子元素

看下面的例子:

.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和第一个.childtop margin叠加,导致.parent1.parent2之间的边距为40px

demo2:

还是用上面的代码,.parent2中的.child中的top marginbottom 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是上面的第四种情况,元素自身的外边距topbottom发生折叠,我们可以看出.container的高度为90px,这里可以看到margin-testtopbottom外边距发生了折叠。


如何避免外边距叠加

上面讲了外边距的叠加,那如何避免呢,其实只要破坏上面讲到的四个条件中的任何一个即可:毗邻两个或多个普通流垂直方向

  • 浮动元素不会与任何元素发生叠加,也包括它的子元素
  • 创建了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、不包含子元素,那么它自身的外边距会发生叠加
两个或多个块级盒子的垂直相邻边界会重合。结果的边界宽度是相邻边界宽度中最大的值。如果出现负边界,则在最大的正边界中减去绝对值最大的负边界。如果没有正边界,则从零中减去绝对值最大的负边界。注意:相邻的盒子可能并非是由父子关系或同胞关系的元素生成。
但是边界的重叠也有例外情况:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值