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

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

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

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

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

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


当前回答

我们要解决什么问题?

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

包含子浮动。这意味着所讨论的元素使自己足够高,以包装所有浮动后代。(他们不会在外面闲逛。) 将子代与外部浮标隔离。这意味着元素内部的后代应该能够使用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的一切都是错误的。

其他回答

与其他clearfix不同,这是一个没有容器的开放式clearfix

其他清除操作要么要求被浮动元素位于标记良好的容器中,要么需要额外的语义上为空的<div>。相反,明确分离内容和标记需要严格的CSS解决方案来解决这个问题。

仅仅因为需要标记浮点数的结尾,就不允许进行无人值守的CSS排版。

如果后者是你的目标,浮点数应该对任何围绕它的东西(段落、有序和无序列表等)保持开放,直到遇到“clearfix”。例如,clearfix可以通过一个新标题来设置。

这就是为什么我使用以下clearfix与新标题:

h1 {
    clear: both;
    display: inline-block;
    width: 100%;
}

这个解决方案在我的网站上被广泛使用,以解决以下问题:浮动的微型对象旁边的文本很短,下一个清除对象的上边距不受尊重。

它还可以防止从站点自动生成pdf时的任何人工干预。 这是一个示例页面。

假设你正在使用这个HTML结构:

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

下面是我将使用的CSS:

div#container {
    overflow: hidden;    /* makes element contain floated child elements */
}

div#content, div#sidebar {
    float: left;
    display: inline;    /* preemptively fixes IE6 dobule-margin bug */
}

我一直使用这个集合,它对我来说工作得很好,即使在IE6中也是如此。

根据所生成的设计,下面每种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.

如果浮动容器有父元素,在ie6中使用overflow:hidden/auto和height就足够了。

#测试中的任何一个都可以工作,下面所述的HTML可以清除浮动。

#test {
  overflow:hidden; // or auto;
  _height:1%; forces hasLayout in IE6
}

<div id="test">
  <div style="floatLeft"></div>
  <div style="random"></div>
</div>

如果这在ie6中不能正常工作,只需要浮动父节点来清除浮动。

#test {
  float: left; // using float to clear float
  width: 99%;
}

从来没有真正需要任何其他类型的清理。也许是我编写HTML的方式。

我总是浮动网格的主要部分,并应用clear:两者;到页脚。这并不需要额外的div或类。