Micro clearfix 负底边距不起作用

Micro clearfix negative bottom margins don't work

知道为什么负边距不适用于应用了 clearfix 的容器吗?

示例:https://jsfiddle.net/tuotckk4/

.cf:after {
  content:"";
  display:block;
  clear:both;
}
.col {
  float: left;
  width: 50%;
  margin-bottom: 50px;
}
.wrapper {
  margin-bottom: -50px;
}
.wrapper-alt {
  margin-bottom: -50px;
  overflow: hidden;
}
<div class="wrapper cf">
  <div class="col">column 1</div>
  <div class="col">column 2</div>
  <div class="col">column 3</div>
  <div class="col">column 4</div>
</div>
<p>Something at bottom</p>
<hr />
<div class="wrapper-alt">
  <div class="col">column 1</div>
  <div class="col">column 2</div>
  <div class="col">column 3</div>
  <div class="col">column 4</div>
</div>
<p>Something at bottom</p>

在第一个示例中,-50px 的负边距无效。在第二个例子中,使用 overflow: hidden 效果很好。

我知道我可以使用 overflow: hidden 但我想知道为什么 clearfix 上的底部边距不起作用。是否可以在不使用额外包装器元素的情况下使其工作?

加边框更清晰:

p {
  border: 1px solid;
}
.cf:after {
  content:"";
  display:block;
  clear:both;
}
.col {
  float: left;
  width: 50%;
  margin-bottom: 50px;
}
.wrapper {
  margin-bottom: -50px;
}
.wrapper-alt {
  margin-bottom: -50px;
  overflow: hidden;
}
<div class="wrapper cf">
  <div class="col">column 1</div>
  <div class="col">column 2</div>
  <div class="col">column 3</div>
  <div class="col">column 4</div>
</div>
<p>Something at bottom</p>
<hr />
<div class="wrapper-alt">
  <div class="col">column 1</div>
  <div class="col">column 2</div>
  <div class="col">column 3</div>
  <div class="col">column 4</div>
</div>
<p>Something at bottom</p>

该段落确实因为负边距而上升,但该段落内的文字没有。

那是因为文本不能与 float:

的边距框重叠

the current and subsequent line boxes created next to the float are shortened as necessary to make room for the margin box of the float.

如果您使用 overflow: hidden,您将建立一个新的块格式化上下文。浮动仅在它们参与的块格式上下文中有效,因此段落不受影响。

还有其他方法可以建立新的块格式化上下文,请参阅Floating elements within a div, floats outside of div. Why?

在第一个示例中,p 元素框确实受到包装器上负边距的影响,但由于浮动 .col 元素被清除,其中的文本被下推通过它前面的 clearfix。

这个 clearfix 还防止包装器的负边距从 collapsingp 元素 - 如果你删除它,整个包装器会向上移动,连同 p, 看起来好像两个元素之间的单个负边距导致两个元素都被移动。

overflow: hidden 导致包装器建立一个 block formatting context,它无需 clearfix hack 即可隔离浮动。这允许 p 元素受到包装器上的负边距的影响,而浮动不会妨碍。

没有包装器你真的做不到。没有一个,你可以给负边距的唯一其他元素是 p 本身的负上边距,当你这样做时,它会随着它自己的上边距恰好是的任何元素的边距折叠与(浮动从流动中取出,因此它们永远不会中断保证金崩溃)相邻。

最好的办法是坚持使用带有 overflow: hidden 的包装器。你的浮动无论如何都不太可能溢出你的包装器,这是迄今为止防止浮动干扰布局其余部分的最干净的方法(即使它与 clearfix 一样多的 hack)。

如果这一切对您来说听起来很复杂,那是因为它确实很复杂。同时使用浮点数和负边距意味着你将陷入一个痛苦的世界。加入 clearfix hack,事情会变得更加混乱。