一、定义
两个或多个毗邻的普通流中的块元素垂直方向上的margin会折叠
- 这两个或多个外边距没有被非空内容、padding、border 或 clear 分隔开
- 这些 margin 都处于普通流中
注意一点,在没有被分隔开的情况下,一个元素的 margin-top 会和它普通流中的第一个子元素(非浮动元素等)的 margin-top 相邻;只有在一个元素的 height 是 "auto" 的情况下,它的 margin-bottom 才会和它普通流中的最后一个子元素(非浮动元素等)的 margin-bottom 相邻。
二、折叠后 margin 的计算
1)参与折叠的 margin 都是正值:取其中 margin 较大的值为最终 margin 值
2)参与折叠的 margin 都是负值:取的是其中绝对值较大的,然后,从 0 位置,负向位移
3)参与折叠的 margin 中有正值,有负值:先取出负 margin 中绝对值最大的,然后,和正 margin 值中最大的 margin 相加
三、需要特别注意的点
1)相邻的 margin 要一起参与计算,不得分步计算
要注意,相邻的元素不一定非要是兄弟节点,父子节点也可以,即使不是兄弟父子节点也可以相邻。
看以下示例:
<div style="margin:50px;background-color:green;width:50px;">
<div style="margin:-60px 0;">
<div style="margin:150px 0;">A</div>
</div>
</div>
<div style="margin:-100px 0;background-color:green;width:50px;">
<div style="margin:-120px 0;">
<div style="margin:200px 0;">B</div>
</div>
</div>
算 A 和 B 之间的 margin。
错误的计算方式: 先算 A 和其父元素以及其父元素的父元素的折叠,这个值算出来之后,应该是90px,依此法算出 B 的为80px,然后,A 和 B 折叠,margin为90px。
请注意,多个 margin 相邻折叠成一个 margin,计算的时候,应该取所有相关的值一起计算,而不能分开分步来算。
以上例子中,A 和 B 之间的 margin 折叠产生的 margin,是 6 个相邻 margin 折叠的结果,将其 margin 值分为两组:
- 正值:50px,150px,200px
- 负值:-60px,-100px,-120px
根据有正有负时的计算规则,正值的最大值为200px,负值中绝对值最大的是-120px,所以,最终折叠后的 margin 应该是 200 + (-120) = 80px
2)元素自身的 margin-bottom 和 margin-top 相邻时也会折叠
自身 margin-bottom 和 margin-top 相邻,只能是自身内容为空,垂直方向上 border、padding 为0
3)浮动元素、inline-block 元素、绝对定位元素的 margin 不会和垂直方向上其他元素的 margin 折叠,即使和它相邻的子元素也不会发生折叠。
4)创建了块级格式化上下文的元素,不和它的子元素发生 margin 折叠