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

Tem*_*fif -6 html css margin css3 css-float

更新:Firefox上不显示以下行为.

让我们从以下情况开始:

html {
  background: red;
}

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

div {
  min-height: 50px;
  background-color: pink;
  margin-bottom: 50px;
}
Run Code Online (Sandbox Code Playgroud)
<div></div>
Run Code Online (Sandbox Code Playgroud)

身体用a定义,min-height:100vh我们有一个滚动条,让我们可以看到html.在这里我们有一个保证金塌陷,的边缘div被折叠与机身保证金,从而创造了身体和滚动条后,这个空间.

如果我们参考规范,我们就有这种情况:

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

...

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

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;
}
Run Code Online (Sandbox Code Playgroud)
<div></div>
<div class="l"></div>
<div class="r"></div>
Run Code Online (Sandbox Code Playgroud)

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

所以我的问题是:为什么这样的行为?


我对边缘崩溃的理解是,最后我们只会在某处应用一个边距.通过添加新元素,我希望有以下两种情况之一:

  1. 添加浮动元素将以某种方式取消边缘折叠(这不是这种情况,因为我们没有违反任何规则)
  2. 浮动元素不会受到边缘的影响,因为这个浮动元素与身体边缘折叠并因此移动/施加到身体上.(这是我的逻辑案例)

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

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

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


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

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


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


作为参考:这是从这个问题开始的,@ Alohci在我的回答中强调了这一点,经过一些评论我们都没有得到说服

Bol*_*ock 9

在开始之前,滚动条的问题在所有浏览器中呈现,但Firefox是一个与此处要求的问题不同的问题.当父元素min-height导致边距不相邻时,Firefox不会折叠父元素与其子元素之间的边距.这也是Firefox中已知的规范违规,正在进行并且尚未修复.

现在,关于手头的问题.从第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;
}
Run Code Online (Sandbox Code Playgroud)
<div></div>
<div class="l"></div>
<div class="r"></div>
Run Code Online (Sandbox Code Playgroud)