为啥这三个块级盒的垂直外边距的合并表现不一致?

zengkan0703
  • 1.2k
  1. 三个兄弟元素都根据不同的方法创建了新的BFC(块级格式化上下文),但是三者之间垂直外边距的合并表现不一致。

  2. 这是我的代码demo

  3. 我觉得这个可能涉及到 BFC 的范围问题:

    (1). 如果这三个块在同一个块级格式化上下文(father)中的话,那么他们三个的垂直外边距应该都进行合并;
    (2). 如果这三个块分别在自己创建的块格式化上下文中的话,那他们三个的垂直外边距都不应该合并。

    不过运行结果中,上两个块之间的垂直外边距没有合并,而下两个的却进行合并了。三个块都创建了新的 BFC ,在这个问题上却表现不一致。

希望有理解原理的同行帮忙看看问题出在哪儿,蟹蟹。


2017-01-20更新

经过楼下的点拨,基本发现了原因:第一个块是行内块,第二个块不在正常流,均不符合外边距叠加的条件(中文版规定英文版规定)。而第二个和第三个之间并不是垂直外边距叠加,只是第三个块的 margin-top 被浮动元素覆盖。
查看demo
从上面的 demo 我们可以看出,两个块之间的水平外边距好像也发生了折叠,而外边距折叠是不会发生在水平外边距上的。而且就算是折叠,最终合并后的值应该是 50px 。可以知道右侧创建 BFC 的块的外边距是被浮动元素的外边距覆盖了。

回复
阅读 2.7k
2 个回答
✓ 已被采纳

我来试试能不能把这个事儿说清楚。。。

你的demo里,三个div(.test1,.test2,.test3)都在父级.father创建的BFC中,这个符合发生垂直外边距重合的条件。但是,垂直外边距重合还有另一个条件,即发生重合的两个元素是in-flow的块级元素。

对此,W3C的原文是:
both belong to in-flow block-level boxes that participate in the same block formatting context
https://www.w3.org/TR/CSS2/bo...

这里的问题在于,三个div(.test1,.test2,.test3)到底是不是in-flow的块级元素:

.test1设置了display:inline-block,所以在normal flow里视作inline,不是块级元素;你可以尝试将三个.test1放在一起,他们不会发生外边距重合;

.test2设置了float:leftfloat的元素不在normal flow里,所以也不会发生重合。例如将三个.test2放在一起,他们也不会发生外边距重合

.test3只设置了overflow,没有改变div的属性,所以还是块级元素;如果将三个.test3放在一起,他们会发生外边距重合;

但是为什么2和3的边距发生了重合呢?事实上,2和3的重合并不是外边距重合(Collapsing margins)。外边距重合(Collapsing margins)会取多个margin中的最大值作为margin,而如果你把.test3margin-top设为30px,2和3的间距还是20px。而这个间距正是.test2的margin。

这里的原因在于.test2是浮动元素,不在normal flow里。所以.test3margin-top是从.test1margin-bottom开始计算的。而当.test3margin-top过小(小于.test2的总高度),.test3的内容就会紧跟.test2,而.test3margin-top就会跟.test2的元素相重合(实质上是.test3margin-top.test2覆盖)。

PS:这么说有人听懂了么??

1、属于同一个BFC的两个相邻Box的margin会发生重叠。
2、然后并非开启了BFC的相邻元素就不发生垂直外边距重叠。
3、开启BFC的元素和其子元素不发生垂直外边距重叠。
只是开启BFC的方法中的某几种可以一定程度的解决相邻兄弟元素垂直外边距重叠问题。
至于2和3的接触边距为什么发生了重叠我觉得还是浮动影响的问题。

传送门

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏