我有一个古老的问题,一个div包装两列布局。我的侧边栏是浮动的,所以我的容器div不能包装内容和侧边栏。

<div id="container">
  <div id="content"></div>
  <div id="sidebar"></div>
</div>

似乎有很多方法可以修复Firefox中的明显错误:

< br清楚= "所有" / > 溢出:汽车 隐藏溢出:

在我的情况下,唯一一个似乎正确工作的是<br clear="all"/>解决方案,这有点邋遢。溢出:auto给我讨厌的滚动条,溢出:隐藏肯定有副作用。 此外,IE7显然不应该因为它的错误行为而遭受这个问题,但在我的情况下,它遭受的问题和Firefox一样。

目前可用的哪种方法是最稳健的?


当前回答

诚实地;所有的解决方案似乎都是修复渲染错误的黑客…我错了吗?

我发现<br clear="all" />是最简单、最简单的。到处看到class="clearfix"并不能触动那些反对无关的markup元素的人的感情,不是吗?你只是把问题画在了另一幅画布上。

我还使用了display: hidden解决方案,这很好,不需要额外的类声明或HTML标记…但有时您需要元素溢出容器,例如。漂亮的丝带和饰带

其他回答

当我们在div元素中使用float属性时,clearfix就可以解决这个问题。如果我们使用两个div元素一个作为float:left;另一个是float:right;我们可以对两个div元素的父元素使用clearfix。如果我们拒绝使用clearfix不必要的空间填充下面的内容和网站结构将被打破。

你试过这个吗:

<div style="clear:both;"/>

我用这个方法没有任何问题。

我们要解决什么问题?

有两个重要的考虑浮动的东西:

包含子浮动。这意味着所讨论的元素使自己足够高,以包装所有浮动后代。(他们不会在外面闲逛。) 将子代与外部浮标隔离。这意味着元素内部的后代应该能够使用clear: both,并且不能与元素外部的浮点数交互。

块格式化上下文

There's only one way to do both of these. And that is to establish a new block formatting context. Elements that establish a block formatting context are an insulated rectangle in which floats interact with each other. A block formatting context will always be tall enough to visually wrap its floating descendants, and no floats outside of a block formatting context may interact with elements inside. This two-way insulation is exactly what you want. In IE, this same concept is called hasLayout, which can be set via zoom: 1.

有几种方法可以建立块格式化上下文,但我推荐的解决方案是display: inline-block with width: 100%。(当然,使用width: 100%时通常会有一些注意事项,所以使用box-sizing: border-box或将填充、边距和边框放在不同的元素上。)

最健壮的解决方案

float最常见的应用可能是双列布局。(可以扩展为三列。)

首先是标记结构。

<div class="container">
  <div class="sidebar">
    sidebar<br/>sidebar<br/>sidebar
  </div>
  <div class="main">
    <div class="main-content">
      main content
      <span style="clear: both">
        main content that uses <code>clear: both</code>
      </span>
    </div>
  </div>
</div>

现在是CSS。

/* Should contain all floated and non-floated content, so it needs to
 * establish a new block formatting context without using overflow: hidden.
 */
.container {
  display: inline-block;
  width: 100%;
  zoom: 1; /* new block formatting context via hasLayout for IE 6/7 */
}

/* Fixed-width floated sidebar. */
.sidebar {
  float: left;
  width: 160px;
}

/* Needs to make space for the sidebar. */
.main {
  margin-left: 160px;
}

/* Establishes a new block formatting context to insulate descendants from
 * the floating sidebar. */
.main-content {
  display: inline-block;
  width: 100%;
  zoom: 1; /* new block formatting context via hasLayout for IE 6/7 */
}

自己试试吧

去JS Bin玩一下代码,看看这个解决方案是如何从头开始构建的。

传统clearfix方法被认为是有害的

传统的clearfix解决方案的问题是,它们使用两种不同的呈现概念来实现IE和其他所有人的相同目标。在IE中,他们使用hasLayout来建立一个新的块格式化上下文,但对于其他人来说,他们使用生成的框(:after)和clear: both,这不会建立一个新的块格式化上下文。这意味着事情不会在所有情况下都表现相同。关于为什么这样不好的解释,请参见您所知道的关于Clearfix的一切都是错误的。

我已经尝试了所有这些解决方案,当我使用下面的代码时,会自动添加一个大的边距到<html>元素:

.clearfix:after {   
    visibility: hidden;   
    display: block;   
    content: ".";   
    clear: both;   
    height: 0;
}

最后,我通过添加font-size: 0来解决边缘问题;到上面的CSS。

根据所生成的设计,下面每种clearfix CSS解决方案都有其自身的优点。

clearfix确实有有用的应用程序,但它也被用作黑客。在你使用clearfix之前,也许这些现代的css解决方案是有用的:

css flexbox css网格


现代Clearfix解决方案


容器溢出:自动;

清除浮动元素的最简单方法是在包含元素上使用样式overflow: auto。这个解决方案适用于所有现代浏览器。

<div style="overflow: auto;">
  <img
    style="float: right;"
    src="path/to/floated-element.png"
    width="500"
    height="500"
  > 
  <p>Your content here…</p>
</div>

一个缺点是,在外部元素上使用某些边距和填充组合可能会导致滚动条出现,但这可以通过将边距和填充放在另一个包含父元素的元素上来解决。

使用' overflow: hidden '也是一个明确的解决方案,但不会有滚动条,然而使用hidden将裁剪位于包含元素之外的任何内容。

注意:在本例中,浮动元素是一个img标记,但也可以是任何html元素。


Clearfix重新加载

Thierry Koblentz在CSSMojo上写道:最新的clearfix重新加载。他指出,通过放弃对oldIE的支持,解决方案可以简化为一条css语句。此外,当带有clearfix的元素是兄弟元素时,使用display: block(而不是display: table)允许页边距正确折叠。

.container::after {
  content: "";
  display: block;
  clear: both;
}

这是clearfix的最新版本。


旧的Clearfix解决方案

下面的解决方案对于现代浏览器不是必需的,但对于针对较老的浏览器可能有用。

请注意,这些解决方案依赖于浏览器错误,因此只有在上述解决方案都不适合您的情况下才应该使用。

它们大致按时间顺序列出。


"Beat That ClearFix",一个针对现代浏览器的ClearFix

CSS Mojo的Thierry Koblentz指出,当针对现代浏览器时,我们现在可以在属性/值之前删除缩放和::,只需使用:

.container::after {
    content: "";
    display: table;
    clear: both;
}

这个解决方案不支持IE 6/7…是故意的!

Thierry还提供了一个忠告:“如果你从头开始一个新项目,那就去做吧,但不要把这个技术与你现在拥有的技术交换,因为即使你不支持oldIE,你现有的规则也能防止保证金崩溃。”


微Clearfix

最新的和全球采用的clearfix解决方案,Nicolas Gallagher的Micro clearfix。

已知支持:Firefox 3.5+, Safari 4+, Chrome, Opera 9+, IE 6+

.container::before, .container::after {
  content: "";
  display: table;
}
.container::after {
  clear: both;
}
.container {
  zoom: 1;
}

溢出财产

通常情况下,当定位的内容不会显示在容器的边界之外时,这种基本方法是首选的。

http://www.quirksmode.org/css/clearing.html -解释了如何解决与此技术相关的常见问题,即在容器上设置宽度:100%。

.container {
  overflow: hidden;
  display: inline-block;
  display: block;
}

与其使用display属性来为IE设置“hasLayout”,不如使用其他属性来触发元素的“hasLayout”。

.container {
  overflow: hidden;
  zoom: 1;
  display: block;
}

使用overflow属性清除浮点数的另一种方法是使用下划线hack。IE会应用带有下划线前缀的值,其他浏览器不会。缩放属性在IE中触发hasLayout:

.container {
  overflow: hidden;
  _overflow: visible; /* for IE */
  _zoom: 1; /* for IE */
}

虽然这是有效的……使用黑客是不理想的。


PIE:简单的清理方法

这种老式的“易清除”方法的优点是允许定位的元素悬挂在容器的边界之外,代价是更棘手的CSS。

这个解决方案相当古老,但你可以在http://www.positioniseverything.net/easyclearing.html上了解关于“位置就是一切”的所有信息


元素使用"clear"属性

当你快速地将一些东西组合在一起时,快速而肮脏的解决方案(有一些缺点):

<br style="clear: both" /> <!-- So dirty! -->

缺点

It's not responsive and thus may not provide the desired effect if layout styles change based upon media queries. A solution in pure CSS is more ideal. It adds html markup without necessarily adding any semantic value. It requires a inline definition and solution for each instance rather than a class reference to a single solution of a “clearfix” in the css and class references to it in the html. It makes code difficult to work with for others as they may have to write more hacks to work around it. In the future when you need/want to use another clearfix solution, you won't have to go back and remove every <br style="clear: both" /> tag littered around the markup.