协慌网

登录 贡献 社区

我可以使用哪种'clearfix' 方法?

我有一个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 的痛苦相同。

目前我们可以采用哪种方法最强大?

答案

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

clearfix 确实有用,但它也被用作黑客。在使用 clearfix 之前,这些现代 css 解决方案可能很有用:


现代 Clearfix 解决方案


overflow: auto;容器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' 也是一个 clearfix 解决方案,但不会有滚动条,但是使用hidden会裁剪位于包含元素之外的任何内容。

注意:在此示例中,浮动元素是img标记,但可以是任何 html 元素。


Clearfix 重新加载

CSSMojo 上的 Thierry Koblentz 写道: 重新加载了最新的 clearfix 。他指出,通过放弃对 oldIE 的支持,可以将解决方案简化为一个 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 还提供:“ 请注意 :如果你从头开始一个新项目,那就去做吧,但不要把这个技术换成你现在的技术,因为即使你不支持 oldIE,你的现有规则也会阻止利润率下降。“


Micro Clearfix

最新和全球采用的 clearfix 解决方案, Nicolas GallagherMicro 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 - 解释如何解决与此技术相关的常见问题,即在容器上设置width: 100%

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

不是使用display属性为 IE 设置 “hasLayout”,而是可以使用其他属性来触发元素的 “hasLayout”

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

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

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

虽然这很有效但是使用黑客并不理想。


PIE:简易清算方法

这种较旧的 “Easy Clearing” 方法的优点是允许定位元素悬挂在容器边界之外,但代价是更棘手的 CSS。

这个解决方案很老了,但你可以学到所有关于位置就是一切的简单清理: http//www.positioniseverything.net/easyclearing.html


元素使用 “清除” 属性

快速和肮脏的解决方案(有一些缺点),当你快速拍打一起时:

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

缺点

  • 如果布局样式基于媒体查询而改变,则它不响应并因此可能不提供期望的效果。纯 CSS 的解决方案更理想。
  • 它添加了 html 标记,而不必添加任何语义值。
  • 它需要每个实例的内联定义和解决方案,而不是对 hss 中 css 和类引用中的 “clearfix” 的单个解决方案的类引用。
  • 它使代码很难与其他人合作,因为他们可能不得不编写更多的黑客来解决它。
  • 将来,当您需要 / 想要使用另一个 clearfix 解决方案时,您将不必返回并删除标记周围散布的每个<br style="clear: both" />标记。

我们试图解决什么问题?

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

  1. 含有后代花车。这意味着所讨论的元素使其自身足够高以包裹所有浮动后代。 (他们不会挂在外面。)

    浮动内容挂在其容器外

  2. 从外面漂浮的绝缘后代。这意味着元素内部的后代应该能够使用clear: both并且它不与元素外部的浮点交互。

    <code> clear:两者</ code>与DOM中其他位置的浮点进行交互

阻止格式化上下文

只有一种方法可以做到这两点。那就是建立一个新的块格式化上下文 。建立块格式化上下文的元素是一个绝缘矩形,其中浮点数相互作用。块格式化上下文总是足够高,可以在视觉上包装其浮动后代,并且块格式化上下文之外的浮点数可以与内部元素交互。这种双向绝缘正是您想要的。在 IE 中,这个相同的概念叫做hasLayout ,可以通过zoom: 1设置zoom: 1

有几种方法可以建立块格式化上下文,但我推荐的解决方案是display: inline-blockwidth: 100% 。 (当然,使用width: 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 来建立一个新的块格式化上下文,但是对于其他人来说,他们使用生成的框( :after )和clear: both ,它们不会建立新的块格式化上下文。这意味着在所有情况下事情都不会相同。有关为什么这是坏的解释,请参阅有关 Clearfix 的所有内容都是错误的

新标准,由Inuit.cssBourbon 使用 - 两个使用非常广泛且维护良好的 CSS / Sass 框架:

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

笔记

请记住,clearfixes 本质上是一个很好的方式,可以灵活地为 Flexbox 布局提供什么。 CSS 浮动最初设计用于内联流内容 - 如长文本文章中的图像 - 而不是网格布局等。如果您的目标浏览器支持 flexbox ,那么值得研究。

这不支持 IE7。你应该支持 IE7。这样做会继续使用户暴露于不固定的安全漏洞,并使所有其他 Web 开发人员的生活更加艰难,因为它减少了用户和组织切换到现代浏览器的压力。

这个 clearfix 是由 Thierry Koblentz于 2012 年 7 月宣布和解释的 。它从Nicolas Gallagher 的 2011 微型 clearfix 中减轻了不必要的重量。在此过程中,它释放了一个伪元素供您自己使用。这已经更新为使用display: block而不是display: table (再次归功于 Thierry Koblentz)。