为什么这个非浮动保证金会随着浮动而崩溃?

Bol*_*ock 4 css css-float

在调查关于清除漂浮物的这个问题时,我遇到了一个特殊的情况,边缘和间隙与非浮动的盒子.

根据规范第8.3.1节,任何一方都不应发生保证金崩溃

  • 产生边距的至少一个元素是浮点数,或
  • 通关是阻碍的.

但是,考虑一系列浮箱,其中最后一个清除其余的:

<div class="container">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
</div>
Run Code Online (Sandbox Code Playgroud)
div.container > div {
    float: left;
    width: 50px;
    height: 50px;
    margin: 10px;
}

div.container > div:last-child {
    clear: left;
}
Run Code Online (Sandbox Code Playgroud)

正如您所料,每个盒子之间的水平和垂直间隙都是20像素宽.垂直边距不会崩溃.

但是,当清除元素没有浮动时,它会向上跳10个像素,就好像它的上边距与其正上方的浮动边缘一样坍塌.

此行为完全违反上面列出的两个条件:

  1. 有通关.
  2. 为了发生间隙,首先必须有一些其他浮子清除.清算单元本身没有浮动的事实不应该是相关的.

这种行为似乎在所有浏览器中都是一致的,包括不到最新版本的IE.

也就是说,我并没有像我的手背那样声称知道CSS浮动模型,所以......其他人可以解释为什么会发生这种情况吗?

Bol*_*ock 7

没关系,我想我是自己找到的.看起来我的问题中的以下假设是错误的(告诉你我没有完全了解CSS浮点模型):

清算单元本身没有浮动的事实不应该是相关的.

在描述该属性的第9.5.2节中clear,它说:

通过首先确定元素的顶部边界边缘的假设位置来计算设置"清除"的元素的间隙.如果元素的'clear'属性为'none',则该位置是实际顶部边界边缘的位置.

如果元素顶部边界边缘的假设位置未超过相关浮点数,则引入间隙,并且边距根据8.3.1中的规则崩溃.

然后将间隙量设置为以下值中的较大值:

  1. 即使在要清除的最低浮点的底部外边缘处放置块的边界边缘所需的量.
  2. 将块的顶部边缘边缘放置在其假设位置所需的量.

在该部分的下方,它说:

在浮动元素上设置属性时,会导致修改浮点定位规则.添加了一个额外的约束(#10):

  • 浮动的顶部外边缘必须低于所有早期左浮动框的底部外边缘(在'clear:left'的情况下),或者所有早期的右浮动框(在'clear:right'的情况下) )或两者('清除:两者').

(强调我的.注意"外边缘"与"边缘"同义,如8.1节所述.)

从本质上讲,这意味着如果清除元素没有浮动并且其顶部边缘不能将其推离浮动区域足够远,则元素被推动到足以使其顶部边界正好位于浮动的底部边缘下方.虽然看起来它的上边距与浮动的下边缘坍塌,但实际上上边距没有任何有意义的影响,因为它没有到达清算元素的边缘.

否则,如果清算元素浮动的,那么它的上边距考虑,可以这么说(在8.3.1规定的规则相一致).

当我写这篇文章的时候,我记得流入的非浮动元素的位置好像浮动从未开始,因为浮动从正常流中取出.换句话说,这是一个非浮动清除元件上设置的任何边距就不会考虑任何花车,不管它是否足够的间隙.例如,当两个clearfloat都设置none在最后一个元素上时,它与其容器的边缘齐平,与第一个浮动元素位于完全相同的位置,尽管在它后面(注意容器块边缘上的边框在它之间折叠)和容器).

最后,在这种特定情况下引入许可的事实实际上并不相关,因为只有当元素的边距通常已经折叠且clear属性设置为时,间隙才会使边缘崩溃none.由于我们在这里讨论浮点数,因此边际崩溃确实不会正常发生,因此最后一个元素是否有清除是不相关的(无论如何都不直接).