边距与浮动元素折叠,为什么会增加额外的边距?

时间:2018-02-14 00:17:18

标签: html css css3 css-float margin

更新 :Firefox上无法显示以下行为。

让我们从以下情况开始:

html {
  background: red;
}

body {
  margin: 0;
  min-height: 100vh;
  background-color: green;
}

div {
  min-height: 50px;
  background-color: pink;
  margin-bottom: 50px;
}
<div></div>

正文定义为min-height:100vh,我们有一个滚动条,可让我们看到html。这里我们有一个 margin-collapsing div的边距与主体边缘折叠,因此在主体和滚动条之后创建了这个空间。

如果我们引用specification我们就有这种情况:

  

当且仅当:

时,两个边距相邻      

...

     

最后一个流入子项的下边距和其父项的下边距   如果父母有'自动'计算身高

div最后一个流入元素,body高度自动,因为我们只指定了最小高度。

现在让我们添加更多可能受此边距影响的元素,并保持边距折叠规则。唯一的方法是添加浮动元素,以使我们的div始终成为最后一个流入元素。

这是新代码:

html {
  background: red;
}

body {
  margin: 0;
  min-height: 100vh;
  background-color: green;
}

div {
  min-height: 50px;
  background-color: pink;
  margin-bottom: 50px;
}
.l {
  width:45%;
  height:50px;
  float:left;
  margin:0;
}
.r {
  width:45%;
  height:50px;
  float:right;
  margin:0;
}
<div></div>
<div class="l"></div>
<div class="r"></div>

正如我们可以清楚地看到的,我们仍然有边缘折叠(因为滚动)并且浮动元素也被相同数量的边距向下推。

所以我的问题是:为什么会出现这种行为?

我对保证金折叠的理解是,最后我们只会在某处应用一个保证金。通过添加新元素,我希望有两种情况之一:

  1. 添加浮动元素会以某种方式取消边距折叠(由于我们没有违反任何规则,因此情况并非如此)
  2. 浮动元素不会受到边缘的影响,因为这个浮动元素会随着身体边缘折叠而移动/施加到身体上。 (这是我的逻辑案例)
  3. 在规范中,我还发现了 complex 语句:

      

    请注意已折叠的元素的位置   对其他元素的位置没有影响   利润率正在崩溃;顶部边框边缘位置仅   布置这些元素的后代所需的。

    我从上面可以理解,其他元素不受边缘折叠的影响,因此保持其初始位置,这解释了浮动元素被推下的原因。 (顺便说一下,我不确定是否属于这种情况)


    如果这是解释,那对我来说有点混乱和不合逻辑。我添加了一个边距,最终我的两个边距清晰可见?

    那么为什么会这样呢?或者我可能错过了规范中的某些内容,而且我们面临的不仅仅是简单的边缘崩溃?

    重要提示 :在回答之前,请注意我不是要找到解决方法或如何避免这种情况。我知道至少有5种方法可以取消边缘折叠(填充,溢出,边框,弹性框等)。我希望了解为什么会发生这种情况。

    参考 :这是由this question开始的,其中@Alohci在我的回答中突出显示了这一点,经过几条评论我们都没有不相信

1 个答案:

答案 0 :(得分:7)

在开始之前,滚动条在所有浏览器中呈现的问题,但Firefox与此处的问题是一个单独的问题。当父元素min-height导致边距不相邻时,Firefox不会折叠父元素与其子元素之间的边距。 It's also a known spec violation in Firefox that's being worked on and yet to be fixed.

现在,关于手头的问题。从第9.5.1节(关于浮标):

  
      
  1. 浮动框的外顶部可能不高于其包含块的顶部。当浮动发生在两个折叠边距之间时,浮动的位置就好像它有一个空的匿名块父级参与流程。这种父母的位置由保证金折叠部分中的规则定义。
  2.   

这句话中的最后一句话很尴尬,但“规则”指的是(和链接)崩溃的定义。虽然您从该部分引用的特定文本是相关的,但它并不能解释为什么浮点数会影响流入div的边际。

这样做:

  

如果框的顶部和底部边距相邻,则边距可能会通过它折叠。在这种情况下,元素的位置取决于它与边缘正在折叠的其他元素的关系。

     
      
  • [...]

  •   
  • 否则,元素的父元素不参与边距折叠,或仅涉及父元素的下边距。元素顶部边框边缘的位置与元素底部边框非零时的位置相同。

  •   

请注意最后一句话。如您所知,具有非零底部边框会取消边距折叠。这意味着浮动的位置就像流入的divbody元素的底部边缘没有崩溃一样,导致浮动看起来像是在底部流入的边缘div

如何判断浮点数是否特别尊重流入div不是崩溃边际的底部边距?通过给body一个比流入div更大的底部边距,并观察它不会影响浮动的位置:

html {
  background: red;
}

body {
  margin: 0;
  margin-bottom: 100px;
  min-height: 100vh;
  background-color: green;
}

div {
  min-height: 50px;
  background-color: pink;
  margin-bottom: 50px;
}
.l {
  width:45%;
  height:50px;
  float:left;
  margin:0;
}
.r {
  width:45%;
  height:50px;
  float:right;
  margin:0;
}
<div></div>
<div class="l"></div>
<div class="r"></div>