Clearfix:网页开发演变的教训

Avatar of Jay Hoffmann
Jay Hoffmann

DigitalOcean 为您旅程的每个阶段提供云产品。从 免费获得 200 美元的积分!

网络社区在很大程度上一直是一个非常开放的地方。因此,许多最佳的开发技术直接在公开场合发生,在博客和论坛上,随着它们被传递和改进而不断发展。我认为跟踪这种创造性交换的过程可能很有趣(也很迷人)。看看一个流行的 CSS 技巧,clearfix,并找出网页设计技术究竟是如何诞生的。

Clearfix,对于那些不知道的人来说,是一个 CSS 技巧,它解决了一个持续存在的错误,该错误发生在两个浮动元素并排堆叠在一起时。当元素以这种方式对齐时,父容器最终会具有 0 的高度,并且很容易对布局造成破坏。您可能只是想将侧边栏放置在主内容块的左侧,但结果将是两个重叠并相互折叠的元素。更糟糕的是,这个错误在不同浏览器中的表现不一致。Clearfix 的发明是为了解决所有这些问题。

来自 *位置就是一切* 的一个早期示例

但是要理解 clearfix,您必须追溯到 2004 年,以及一种名为 Holly 技巧的特定技术。

2004:Holly 技巧和 Clearfix 的起源

Holly 技巧以其创造者 Holly Begevin 的名字命名,她是 CommunityMX 的开发人员和博主。Holly 技巧结合了两种不同的 CSS 技术,这两种技术在 Netscape Navigator 和 Internet Explorer (IE) 4 的时代有效,可以解决一些布局问题。Begevin 注意到,如果您将上述场景中每个浮动元素的高度设置为 1%,问题实际上会自行解决(仅因为它激活了一个完全不同的错误)在 Windows 版 Internet Explorer 中。

不幸的是,1% 技巧在 Mac 上不起作用。为此,Begevin 添加了一个条件注释,该注释在其 CSS 中使用反斜杠,奇怪的是,在旧时代,它会阻止 Mac 版 IE 中的单个 CSS 规则。结果是一个看起来像这样的 CSS 技巧

/* Hides from IE5-mac \*/
* html .buggybox {height: 1%;}
/* End hide from IE5-mac */

我知道很奇怪,但它只会变得更加复杂。

同年 5 月,还需要处理更多浏览器,并非所有浏览器都能够用一行 CSS 修补。Tony Aslett 在他的留言板 CSS Creator 上发布了一个新主题,提出了一种新方法。他将这个技巧称为 clearfix,因为它围绕清除浮动元素来解决问题。

Aslett 的方法利用了当时仍处于起步阶段的 CSS 伪选择器(特别是 :after)来自动清除两个浮动元素。Aslett 第一个版本的 clearfix 存在一个非常大的缺陷。由于从未听说过 Holly 技巧,Aslett 的代码需要一些 JavaScript 来解决专门在 Mac 版 IE 上出现的错误。在那些日子里,JavaScript 是一项相对未经测试的技术,并且以如此基本的方式依赖它并非理想选择。

值得庆幸的是,网络是一个迭代的地方,一位留言板用户将 Aslett 引向了上述 Holly 技巧。通过加入 Begevin 的条件注释,Aslett 能够使他的代码在几乎所有浏览器上都能正常工作,完全不需要 JavaScript。

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

/* Mark Hadley's fix for IE Mac */     
.floatcontainer {
  display: inline-block;
}

/* Hides from IE Mac \*/
* html .floatcontainer {height: 1%;}
.floatcontainer{display:block;}
/* End Hack */

如果您想仔细分析网页历史和创新的重要片段,Aslett 关于 clearfix 的帖子之后的讨论 是一个很好的起点。人们一个接一个地开始尝试这种新技术,在各种奇特的浏览器和设备上对其进行测试。测试完成后,他们会将结果发布到留言线程,有时还会附带一些有用的调整。

例如,用户 *zulaica* 指出,在 Mozilla 浏览器中,必须明确定义浮动元素的底部边框。用户 *pepejeria* 注意到,您可以从内容中省略点,用户 *co2* 在 Apple 首个版本的 Safari 浏览器中测试了 clearfix。每次,Aslett 都会对他的代码进行一些更新,直到经过多次快速迭代后,clearfix 终于准备就绪,并且由于社区的努力,变得非常强大。

2006:Clearfix 进行了更新

但是浏览器一直在进步。Clearfix 代码中一些更奇特的部分之所以有效,是因为旧浏览器中存在一些错误。随着浏览器修复了这些错误,在全新版本中,clearfix 停止工作。当 IE 7 在 2006 年底发布时,需要对该技巧进行一些调整以使其正常工作。

幸运的是,John “Big John” Gallant 在他的博客 *位置就是一切* 上维护着一个页面,其中包含最新版本的 clearfix。在收到读者的反馈后,Gallant 更新了他的博客,以反映 IE 7 的一些新修复程序,这些修复程序使用了一种新型的条件注释,可以在 Internet Explorer 中工作。

<style type="text/css">

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

</style><!-- main stylesheet ends, CC with new stylesheet below... -->

<!--[if IE]>
<style type="text/css">
  .clearfix {
    zoom: 1;     /* triggers hasLayout */
  }  /* Only IE can see inside the conditional comment
    and read this CSS rule. Don't ever use a normal HTML
    comment inside the CC or it will close prematurely. */
</style>
<![endif]-->

用户再次使用自己的浏览器测试了最新的代码,以确保它在所有地方都能正常工作。再次,它在一段时间内有效。

2010:Clearfix 重新加载

事实上,这个版本的 clearfix 会持续到大约 2010 年,当时 Yahoo! 用户界面库 (YUI) 团队发现 clearfix 存在一些问题。例如,Holly 技巧现在早已消失(IE 5 只是遥远的记忆),并且在切换盒模型后,现代浏览器对边距的处理略有不同。

但是 YUI 的人员仍然需要将一个元素与另一个元素对齐。事实上,这种需求越来越大,因为设计师在尝试更高级的网格布局。2010 年,网格布局选项非常少,因此 clearfix 必须正常工作。他们最终对 CSS 规则集做了一些额外的调整,最值得注意的是利用了两个可用的伪选择器(:before:after)来清除任何边距。他们在自己的博客上发布了他们新版本的 clearfix,并将其命名为 “clearfix 重新加载”

.clearfix:before,
.clearfix:after {
  content: ".";    
  display: block;    
  height: 0;    
  overflow: hidden;        
}
.clearfix:after { clear: both; }
.clearfix { zoom: 1 ;} /* IE < 8 */

2011:微型 Clearfix

但是即使在 2010 年发布时,clearfix 重新加载也带来了旧浏览器的一些不必要的负担。高度等于 0 的技巧不再是真正的必需,事实上,当使用 display: table 时,该技巧更可靠。人们开始在 Twitter 和博客上交换该技术的各种变体。在 clearfix 重新加载发布大约一年后,开发人员 Nicolas Gallagher 将这些变体编译成一个更紧凑的版本,他将其恰当地标记为 微型 clearfix

经过多年的反复和细微调整,clear fix 现在只需要四个 CSS 规则

/*
 * For modern browsers
 * 1. The space content is one way to avoid an Opera bug when the
 *  contenteditable attribute is included anywhere else in the document.
 *  Otherwise it causes space to appear at the top and bottom of elements
 *  that are clearfixed.
 * 2. The use of `table` rather than `block` is only necessary if using
 * `:before` to contain the top-margins of child elements.
 */
.cf:before,
.cf:after {
  content: " "; /* 1 */
  display: table; /* 2 */
}

.cf:after {
  clear: both;
}

/*
 * For IE 6/7 only
 * Include this rule to trigger hasLayout and contain floats.
 */
.cf {
  zoom: 1;
}

Clearfix 的终结?

如今,在 clearfix 首次被提出将近 15 年后,它的相关性正在下降。 CSS 网格Flexbox 正在填补网页高级布局的空白。2017 年 1 月,Rachel Andrew 为她的博客撰写了一篇名为 “Clearfix 技巧的终结?” 的文章。在这篇文章中,她描述了一种使用称为 flow-root 的新显示模式规则,用一行代码替换 clearfix 技巧的方法。

.container {
  display: flow-root;
}

我们正在接近 clearfix 将不再需要的日子。

即使没有 flow-root,如今也有很多方法可以创建网格。如果您刚开始接触网页,您几乎没有理由学习它。这是一件好事!从一开始,它就一直是利用现有资源的权宜之计。讽刺的是,如果没有多年来一直致力于破解 clearfix 的开发人员的奉献和实验,我们今天就不会拥有不再依赖它的工具。

喜欢通过类似这样的故事了解网页历史吗?Jay Hoffmann 有一份名为 *网页历史* 的每周通讯,您可以 在这里订阅