保证金与浮动元素一起崩溃,为什么会增加额外保证金?

问题描述 投票:-5回答:1

更新: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。在这里,我们有一个边缘坍塌,div的边缘与身体边缘折叠,从而在身体和滚动条之后创建这个空间。

如果我们参考specification我们有这个案例:

当且仅当以下情况时,两个边距相邻:

...

如果父项具有“自动”计算高度,则最后一个流入子项的下边距和其父项的下边距

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


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

这是新代码:

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. 浮动元素不会受到边缘的影响,因为这个浮动元素与身体边缘折叠并因此移动/施加到身体上。 (这是我的逻辑案例)

在规范中我也发现了这个复杂的陈述:

请注意,已折叠的元素的位置对其折叠边距的其他元素的位置没有影响;顶部边界边缘位置仅用于布置这些元素的后代。

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

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

那么为什么会这样呢?或许我在规范中遗漏了一些东西,而且我们面临的不仅仅是简单的边缘崩溃?


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


作为参考:这是由this question开始的,其中@Alohci在我的回答中强调了这一点,并且在几条评论后我们都没有得到说服

html css css3 css-float margin
1个回答
9
投票

在开始之前,滚动条的问题在所有浏览器中呈现,但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. 浮动盒的外顶部可能不高于其包含块的顶部。当浮动发生在两个折叠边距之间时,浮动的位置就好像它有一个空的匿名块父级参与流程。这种父母的位置由保证金折叠部分中的规则定义。

这句话中的最后一句话很尴尬,但“规则”指的是(和链接)崩溃的定义。虽然您从该部分引用的具体文本是相关的,但它并不能解释为什么浮标尊重流入的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>
© www.soinside.com 2019 - 2024. All rights reserved.