我可以使用哪些“clearfix”方法?

890

我有一个老问题,即 div 包裹两列布局。我的侧边栏是浮动的,因此我的容器 div 无法包裹内容和侧边栏。

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

看起来有许多方法可以解决Firefox中的清除浮动问题:

  • <br clear="all"/>
  • overflow:auto
  • overflow:hidden

在我的情况下,唯一有效的方法似乎是 <br clear="all"/> 解决方案,但该解决方案略显凌乱。 overflow:auto 会生成令人不愉快的滚动条,而 overflow:hidden 可能会产生副作用。 此外,据说IE7由于其不正确的行为而不应受此问题的困扰,但在我的情况下,它与Firefox一样遇到了同样的问题。

目前对我们可用的哪种方法最为稳健?


1
我使用http://www.jqui.net/tips-tricks/css-clearfix/,它帮助我隐藏了那个点 :) - Val
1
IE 6和IE 7怎么办?它们从来没有遵循正确的清除方式。 - Praveen Kumar Purushothaman
现在我们已经过去一年了,是否有任何机会修改正确答案以符合现代的三行 clearfix(在此处概述:http://www.css-101.org/articles/clearfix/latest-new-clearfix-so-far.php),就像大型框架 Bourbon 和 Inuit.css 中使用的那样?请参见我的下面的答案。https://dev59.com/CnVC5IYBdhLWcg3wsTZi#16099501 - iono
29个回答

1065

根据所需的设计,以下每个clearfix CSS解决方案都有其自己的优点。

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


现代 clearfix 解决方案


使用overflow: auto;的容器

清除浮动元素最简单的方法是在包含元素上使用样式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 元素。


清除浮动再升级

CSSMojo上的Thierry Koblentz写道:最新的清除浮动再升级。他指出,通过放弃对旧版IE的支持,该解决方案可以简化为一个CSS语句。此外,使用display:block(而不是display:table)允许在具有clearfix的兄弟元素中正确折叠边距。

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

这是clearfix的最新版本。


旧版Clearfix解决方案

以下解决方案对于现代浏览器来说并不必要,但可能对于针对较老的浏览器有用。

请注意,这些解决方案依赖于浏览器的漏洞,因此仅在上述解决方案均无效时才应使用它们。

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


“Beat That ClearFix”——现代浏览器下的clearfix

CSS Mojo的Thierry Koblentz指出,当我们针对现代浏览器进行设计时,我们可以直接使用以下代码而不需要再写zoom::before属性或值:

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

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

Thierry还提供了:“警告:如果你从头开始一个新项目,那就去做吧,但不要用现有的技术来替换它,因为即使你不支持旧版IE,你现有的规则也可以防止边距折叠。”


微型清除浮动

最近全球采用的清除浮动解决方案,Nicolas Gallagher的微型清除浮动

已知支持: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 - 解释了如何解决与此技术相关的常见问题,即在容器上设置width: 100%

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

与其使用display属性为IE设置"hasLayout",可以使用其他属性来触发元素的"hasLayout"

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

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

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

虽然这有效... 但使用hack并不理想。


PIE:简易清除方法

这种旧的“简易清除”方法的优点是允许定位元素悬挂在容器的边界之外,但代价是需要更加复杂的CSS。

虽然这个解决方案相当老,但您仍然可以在Position Is Everything网站上学习有关简易清除的所有信息:http://www.positioniseverything.net/easyclearing.html


使用“clear”属性的元素

当您需要快速拼凑一些东西时,这是一个快速而不太完美的解决方案(带有一些缺点):

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

缺点

  • 它不具有响应性,因此如果布局样式根据媒体查询更改,可能无法提供所需的效果。纯CSS解决方案更理想。
  • 它添加了HTML标记,而不一定添加任何语义价值。
  • 它需要为每个实例进行内联定义和解决方案,而不是在css中引用单个“clearfix”的类参考,并在html中引用它。
  • 它使其他人难以处理代码,因为他们可能不得不编写更多的hack来解决它。
  • 将来当您需要/想要使用另一个clearfix解决方案时,您不必返回并删除散布在标记中的每个<br style="clear: both" />标记。

26
@David Rivers:":after" 方法并不是一种 hack,因为它并没有利用浏览器解析错误,而是使用 CSS 中的一个特性作为解决方案。此外,与下划线 hack 不同,":after" 在未来浏览器中将得到支持。理想情况下,会有一种 CSS 属性可以应用于元素,使其包含所有内容。 - Beau Smith
7
感谢你的解释。我发现使用":after"选择器的 "easy clearing" 方法比使用"overflow: hidden"更优越,因为它不会裁剪CSS3盒阴影或定位元素。额外的代码行绝对是值得的。 - Aneon
7
我不是在推崇 br clear:both 的解决方案,但我不同意你对它的“脏标签”评价。相比于浏览器需要加载的几行 CSS 代码,只有一行短小的 HTML 代码,所以“增加负荷速度变慢”的论点似乎有些可笑。至于“语义价值”的论点,一个带有 clear:both 的 br 标签要比试图理解一堆奇怪的 css 代码更容易理解。br clear:both 很简短明了,而且在我看来并不会影响“专业性”。 - Vigrond
17
与流行观点相反,overflow: hiddenoverflow: auto 并不会清除浮动(将其归类为“clearfix”是错误的)。相反,它会使元素创建一个新的格式化上下文,以便在其中容纳浮动。这会导致容器高度伸展以包含它们。没有任何清除操作涉及到——也就是说,你仍然可以根据你的布局选择是否清除容器中的浮动。 - BoltClock
3
不再支持IE7,请使用此处描述的三行方法进行更新(http://www.css-101.org/articles/clearfix/latest-new-clearfix-so-far.php)。 - iono
显示剩余19条评论

73

我们要解决的问题是什么?

在浮动元素时,有两个重要的考虑因素:

  1. 包含后代浮动元素。 这意味着所讨论的元素会使自身变高,以包裹所有浮动的后代元素。(它们不悬挂在外面。)

    浮动的内容悬挂在容器外面

  2. 隔离内部浮动元素和外部浮动元素之间的影响。 这意味着元素内部的后代元素应该能够使用clear: both而不与元素外部的浮动元素产生交互。

    <code>clear: both</code>与文档中其他地方的浮动元素的交互

块级格式化上下文

只有一种方法可以同时解决这两个问题,那就是建立一个新的块级格式化上下文。建立块级格式化上下文的元素是一个被隔离的矩形,其中浮动元素互相影响。块级格式化上下文始终足够高,以视觉方式包装其浮动后代元素,而且没有位于块级格式化上下文之外的浮动元素可以与其中的元素产生交互。这种双向隔离正是您想要的效果。在IE中,这个概念称为hasLayout,可以通过zoom: 1来设置。

有几种方法可以建立块级格式化上下文,但我推荐的解决方案是使用display: inline-blockwidth: 100%。(当然,使用width: 100%时有一些常见注意事项,因此请使用box-sizing: border-box或将paddingmarginborder放在不同的元素上。)

最稳健的解决方案

浮动元素最常见的应用可能是双列布局。(可以扩展到三列。)

首先是标记结构。

<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来建立新的块级格式上下文,但对于其他浏览器,它们使用具有clear:both属性的生成框体(:after),这不会建立新的块级格式上下文。这意味着在所有情况下都不会表现得一致。关于为什么这样做是有问题的,请参见Everything you Know about Clearfix is Wrong


“使用width: 100%的常见注意事项是什么?” 此外,您是否建议在§2的¶1中使用zoom: 1 - Baumr
如果避免使用“position: absolute”,那么就可以正常显示,并且将成为相同的渲染概念,这是正确的。 - Baumr
我明白了。渲染概念是指如果overflow:hidden实现了与hasLayout有所不同的东西? - Baumr
hasLayout的情况是否包括提到的某些CSS声明?还是它们都是独立的? - Baumr
2
在 https://dev59.com/vnI-5IYBdhLWcg3wj5FG 上了解更多关于 hasLayout 的内容。我认为它与建立新的块级格式化上下文是同义词。这些元素本质上负责所有后代元素的布局。其中一个结果是,建立新的块级格式化上下文的元素包含浮动的后代元素,而元素外部的浮动不会与内部的 clear: left|right|both 元素交互。(这在上面的答案中有提到。) - Chris Calo
显示剩余2条评论

56

最新的标准,被Inuit.cssBourbon这两个广泛使用且维护良好的CSS/Sass框架所采用:

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

注意事项

请记住,clearfix本质上是一种hack,而现在flexbox布局可以以更加简单和智能的方式提供此功能。CSS浮动最初是为内联内容流设计的,如长文本文章中的图像,而不是用于网格布局等。除非您专门针对旧版(非Edge)Internet Explorer,否则您的目标浏览器支持flexbox,因此学习它是值得的。

这不支持IE7。您不应该支持IE7。这样做会继续使用户面临未修复的安全漏洞,并使所有其他Web开发人员的生活更加困难,因为它减轻了用户和组织转向更安全的现代浏览器的压力。

这个clearfix是由Thierry Koblentz在2012年7月宣布并解释的。它从Nicolas Gallagher的2011年微清除中去掉了不必要的重量。在此过程中,它为您自己的使用释放了一个伪元素。这已更新为使用display:block而不是display:table(再次感谢Thierry Koblentz)。


4
希望你的答案能获得更多的赞,因为我完全同意你的观点。再次强调,现在是2013年,我真诚地认为这是人们应该使用的解决方案。 - rafaelbiten
2
同意。请访问http://theie7countdown.com/,检查您自己的分析数据,希望您能看到IE7不值得您花费时间。 - Justin
1
@Justin同意;你的个人分析将说明这一点。我认为倒计时网站已经有一段时间没有更新了,最好使用caniuse的统计数据,该数据将全球IE7的使用率定为0.39%。 - iono
1
希望像clearfix这样的hack很快就会因为使用flexbox而不是浮动来进行布局而变得不再必要。 - iono
无论你多么反对支持IE7,但如果业务端要求支持这些用户(出于不同的原因-通常是钱),你将不得不这样做,无论你对这个问题的感受如何。 - Kris Selbekk
显示剩余2条评论

29

我建议使用以下内容,这是从http://html5boilerplate.com/获取的。

/* >> The Magnificent CLEARFIX << */
.clearfix:after { 
  content: "."; 
  display: block; 
  height: 0; 
  clear: both; 
  visibility: hidden; 
}
.clearfix { 
  display: inline-block;  
}
* html .clearfix {  
  height: 1%;  
} /* Hides from IE-mac \*/
.clearfix {  
  display: block;  
}

9
谁还记得IE-mac?为什么要因为不再相关的问题而使事情变得如此复杂? - Ilya Streltsyn

25

overflow属性可用于清除无需额外标记的浮动:

.container { overflow: hidden; }

这适用于所有浏览器,除了IE6,你只需要启用hasLayout(我首选的方法是使用zoom):

.container { zoom: 1; }

http://www.quirksmode.org/css/clearing.html


3
在PS3浏览器中,"overflow: hidden"不起作用。虽然大多数人不需要它工作,但对于我们正在尝试针对业务原因的PS3上的网站而言,这是最重要的问题。烦死了。 - gtd
1
如果您确实希望某些内容悬挂在容器外部,那么这将是一个问题。 - Simon East
overflow: hidden 有一个副作用,会裁剪内容。 - Chris Calo
9
overflow:hidden 的作用是裁剪内容;它的副作用是清除容器。;-) - Tamlyn
overflow:auto 也会触发块级格式化上下文,并且不会裁剪内容。 - Harry Robbins

18
我发现官方的CLEARFIX方法有个bug: 点没有字体大小。 如果你将 height=0 设置,并且你的DOM-树中的第一个元素具有"class clearfix"类,那么你的页面底部始终会有12像素的边距 :)
你需要像这样修复它:
/* float clearing for everyone else */
.clearfix:after{
  clear: both;
  content: ".";
  display: block;
  height: 0;
  visibility: hidden;
  font-size: 0;
}

现在它是YAML-Layout的一部分... 看看它吧 - 非常有趣! http://www.yaml.de/en/home.html


16

这是一个非常整洁的解决方案:

/* For modern browsers */
.cf:before,
.cf:after {
    content:"";
    display:table;
}

.cf:after {
    clear:both;
}

/* For IE 6/7 (trigger hasLayout) */
.cf {
    zoom:1;
}

已知在Firefox 3.5+、Safari 4+、Chrome、Opera 9+和IE 6+中可用。

尽管使用:before选择器不是清除浮动所必需的,但它可以防止现代浏览器中顶部边距发生折叠。这确保了在应用zoom:1时与IE 6/7保持视觉一致性。

来自http://nicolasgallagher.com/micro-clearfix-hack/


1
是的,截至2011年中期,这是我最喜欢的解决方案。它允许您在必要时将对象定位在包含框之外(避免使用overflow: hidden)。 - Simon East

11

Bootstrap中的Clearfix:

.clearfix {
  *zoom: 1;
}

.clearfix:before,
.clearfix:after {
  display: table;
  line-height: 0;
  content: "";
}

.clearfix:after {
  clear: both;
}

这是哪个版本的Bootstrap? - Eric

9
我只是使用:“-”
.clear:after{
  clear: both;
  content: "";
  display: block;
}

兼容IE8+,效果最佳 :)


在IE7中无法工作,因为它不支持CSS伪元素。 - superluminary
4
这就是他说“兼容IE8+”的原因。大多数网站不再需要支持IE7,它在全球使用率不到1%。http://theie7countdown.com/ - Justin

9
鉴于回复数量众多,我本来不想发帖。然而,这种方法可能会帮助某些人,就像它帮助了我一样。
尽可能避免使用浮动。
值得一提的是,我像避免埃博拉病毒一样避免使用浮动。有很多原因,我并不孤单;阅读Rikudo关于什么是clearfix的回答,你就会明白我的意思。用他自己的话说:……使用浮动元素进行布局越来越不鼓励,更好的替代方案也越来越多…… 除了浮动之外,还有其他好的(有时更好的)选择。随着技术的进步和改进,flexbox (以及其他方法)将被广泛采用,浮动将成为一个不好的记忆。也许CSS4?

浮动行为不当和清除失败

首先,有时候你可能认为你的html布局是安全的,直到你的救生圈被刺破,你的html流开始下沉:

在下面的Codepen http://codepen.io/omarjuvera/pen/jEXBya 中,使用 <div classs="clear"></div>(或其他元素)来清除浮动是常见的做法,但是这种方法受到反对并且违反语义化。

<div class="floated">1st</div>
<div class="floated">2nd</div>
<div class="floated">3nd</div>
<div classs="clear"></div> <!-- Acts as a wall -->
<section>Below</section>

CSS

div {
    border: 1px solid #f00;
    width: 200px;
    height: 100px;
}

div.floated {
    float: left;
}

.clear {
    clear: both;
}
section {
    border: 1px solid #f0f;
}

然而,就在你认为你的浮动元素已经可以使用了...砰!随着屏幕尺寸变得越来越小,你会看到像下面这个图形一样的奇怪行为(同http://codepen.io/omarjuvera/pen/jEXBya):

float bug sample 1

为什么你应该关注这个问题? 大约80%(或更多)的使用设备是具有小屏幕的移动设备。桌面电脑/笔记本电脑不再是主导。


问题并不止于此

浮动布局存在的问题不仅仅是这一个。虽然有些人可能会说你只需要将浮动元素放在容器中即可解决问题,但正如你在codepen和图示中看到的那样,情况并非如此。这似乎使情况变得更糟:

HTML

<div id="container" class="">
  <div class="floated">1st</div>
  <div class="floated">2nd</div>
  <div class="floated">3nd</div>
</div> <!-- /#conteiner -->
<div classs="clear"></div> <!-- Acts as a wall -->
<section>Below</section>

CSS

#container {
  min-height: 100px; /* To prevent it from collapsing */
  border: 1px solid #0f0;
}
.floated {
    float: left;
    border: 1px solid #f00;
    width: 200px;
    height: 100px;
}

.clear {
    clear: both;
}
section {
    border: 1px solid #f0f;
}

关于结果呢?

它完全一样! float bug sample 2

至少你知道,你会开始一个CSS派对,邀请各种选择器和属性参加派对;让你的CSS变得比你开始时更混乱。只是为了修复你的浮动问题。


CSS清除浮动救星

这个简单而非常适应的CSS代码是一个美丽和“救世主”:

.clearfix:before, .clearfix:after { 
    content: "";
    display: table;
    clear: both;
    zoom: 1; /* ie 6/7 */
}

就是这样!它确实可以在不破坏语义的情况下工作,我还提到了它可以工作吗?

来自同一样本...HTML

<div class="clearfix">
    <div class="floated">1st</div>
    <div class="floated">2nd</div>
    <div class="floated">3nd</div>
</div>
<section>Below</section>

CSS

div.floated {
    float: left;
    border: 1px solid #f00;
    width: 200px;
    height: 100px;
}
section {
        border: 4px solid #00f;
}


.clearfix:before, .clearfix:after { 
    content: "";
    display: table;
    clear: both;
    zoom: 1; /* ie 6/7 */
}

现在我们不再需要使用 <div classs="clear"></div> <!-- 作为隔板 --> 以满足语义要求,这并不是唯一的好处。这个clearfix对于任何屏幕大小都是响应式的,在其最简单的形式中不使用 @media。换言之,它将保持您的浮动容器受控,并防止洪水泛滥。最后,它为旧版本的浏览器提供了支持,所有这些功能都只需一个小小的清除浮动(clearfix) =)。

以下是clearfix内容:

.clearfix:before, .clearfix:after { 
    content: "";
    display: table;
    clear: both;
    zoom: 1; /* ie 6/7 */
}

2
元素具有“clear”类名不起作用的原因是您的属性“class”错误。您写的是“classs”,多了一个“s”。 - chestnut
你的例子即使纠正了错误,也没有证明你所声称的内容。 - Reinstate Monica -- notmaynard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接