问题描述
更新:以下行为在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
的边距与主体边距一起折叠,因此在主体和滚动条之后创建了该空间.
如果我们引用规范,我们将拥有此情况:
div
是最后流入的元素,body
具有高度自动功能,因为我们仅指定了最小高度.
现在,让我们添加更多可能受此边距影响的元素,并保留边距折叠规则.唯一的方法是添加 floated 元素,以使我们的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>
我们可以清楚地看到,由于滚动的缘故,我们仍然有边际崩溃,并且浮动元素也被以相同的边际量向下推.
所以我的问题是:为什么这样的行为?
我对保证金倒闭的理解是,最后,我们仅在某处应用了一个保证金.通过添加新元素,我期望会出现以下两种情况之一:
- 添加浮动元素将以某种方式取消边距崩溃的(因为我们没有违反任何规则,所以不可能是这种情况)
- 浮动元素不会受到边缘的影响,因为该元素随着身体边缘塌陷并因此移动/应用到了身体. (这对我来说是一个逻辑案例)
在规范中,我还发现了以下 complex 语句:
从以上内容可以理解,其他元素不受边界收缩的影响,因此保持其初始位置,这解释了为什么浮动元素被向下推. (我不确定情况是否如此)
如果这是解释,那么这对我来说有点混乱和不合逻辑.我添加了一个边距,最后却得到了两个清晰可见的边距?
那为什么会这样呢?还是我错过了规范中的某些内容,而我们所面临的不仅仅是简单的边际崩溃?
重要通知:在回答之前,请注意,我不是在寻求解决此问题的方法,也不是如何避免此问题的方法.我至少知道5种取消边距折叠的方法(填充,溢出,边框,弹性框等).我想了解为什么会发生这种情况.
供参考:此操作由,其中 @Alohci 在我的回答中强调了这一点,经过几番评论,我们俩都没有不要被说服
在开始之前,在所有浏览器中都呈现滚动条的问题,但Firefox是与此处所询问的问题分开的问题.当父元素的min-height
导致边界不相邻时,Firefox不会折叠父元素与其子元素之间的边界. 这也是已知的Firefox规范违规行为,目前仍在研究中是固定的.
现在,谈谈眼前的问题.从第9.5.1节开始(在浮点数上):
此引号中的最后一句很尴尬,但是规则"是指(和链接)崩溃的定义.虽然您从该部分引用的特定文本是相关的,但并未说明浮动内容为何尊重流入量div
的边距.
这样做:
注意最后一句话.如您所知,底部边框不为零将消除边距折叠.这意味着浮子的位置好像流入的div
和body
元素 did not 的底边塌陷,导致浮子看起来尊重in的底边-flow 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>
Update: the below behavior is not visible on Firefox.
Let's start with the following situation:
html {
background: red;
}
body {
margin: 0;
min-height: 100vh;
background-color: green;
}
div {
min-height: 50px;
background-color: pink;
margin-bottom: 50px;
}
<div></div>
The body is defined with a min-height:100vh
and we have a scroll bar that allow us to see the html
. Here we are having a margin-collapsing, the margin of the div
is collapsed with the body margin and thus create this space after the body and the scroll bar.
If we refer to the specification we have this case:
the div
is the last in-flow element and body
has height auto as we only specified min-height.
Now let's add more elements that may be affected by this margin and keep the rules of margin-collapsing. The only way to do this is to add floated elements to keep our div
always the last in-flow element.
Here is the new code:
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>
As we can clearly see, we still have margin collapsing (because of the scroll) AND the floated elements are also pushed down by the same amount of the margin.
So my question is: why such behavior?
My understanding of margin-collapsing is that at the end we will have only one margin applied somewhere. By adding new elements, I am expecting to have one of this two situations:
- Adding the floated elements will somehow cancel the margin-collapsing (this cannot be the case as we are not breaking any rule)
- The floating elements will not get affected by the margin as this one collapsed with body margin and thus moved/applied to the body. (This is a logic case for me)
In the specification I also found this complex statement:
I understand from the above that the other elements get not affected by the margin-collapsing and thus keep their initial position which explain why the floated elements are pushed down. (I am not sure if this is the case by the way)
If this is the explanation then it's a bit confusing and illogical for me. I added one margin and I end up having two margins that are clearly visible?
So why such behavior? Or maybe I missed something in the specification and we are facing more than a simple margin-collapsing?
Important notice: Before answering, please note that I am not looking for a fix to this or how to avoid this. I know at least 5 ways to cancel margin-collapsing (padding, overflow, border, flexbox,etc..).I am looking to understand why such thing happen.
For the reference: this started by this question where @Alohci highlighted this in my answer and after few comments we both didn't get convinced
Before I start, the issue of scrollbars being rendered in all browsers but Firefox is a separate issue from what is being asked about here. Firefox does not collapse margins between a parent element and its children when the parent's min-height
results in the margins not being adjoining. It's also a known spec violation in Firefox that's being worked on and yet to be fixed.
Now, on to the issue at hand. From section 9.5.1 (on floats):
The last sentence in this quote is awkward, but "the rules" refer (and link) to the definition of collapsing through. While the specific text that you cite from that section is relevant, it doesn't explain why the floats respect the margin of the in-flow div
.
This does:
Note the last sentence. Having a non-zero bottom border cancels margin collapsing, as you know. This means that the floats are positioned as if the bottom margins of the in-flow div
and the body
element did not collapse, resulting in the floats appearing to respect the bottom margin of the in-flow div
.
How do I tell that the floats specifically respect the bottom margin of the in-flow div
and not the collapsed margin? By giving body
a larger bottom margin than that of the in-flow div
and observing that it does not affect the position of the floats:
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>
这篇关于保证金因浮动元素而崩溃,为什么还要增加额外的保证金?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!