网络社区在很大程度上一直是一个非常开放的地方。因此,许多最佳的开发技术直接在公开场合发生,在博客和论坛上,随着它们被传递和改进而不断发展。我认为跟踪这种创造性交换的过程可能很有趣(也很迷人)。看看一个流行的 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 有一份名为 *网页历史* 的每周通讯,您可以 在这里订阅。
overflow: auto;
在容器上很简单,对吧?:)如果容器显示的工具提示或下拉菜单的大小(宽度或高度)大于容器,则可能会显示滚动条,因为元素边界(或者,如果值为
overflow: hidden;
,则会截断工具提示和下拉菜单视图)。您认为这是 bug 还是预期行为?:)
这不是 bug。作者很好地介绍了该技术的演变历史,所以我不想贬低这篇文章。它很棒。但他不应该将其称为 bug。当浮动元素导致容器“折叠”时,是因为浮动将元素移出了正常流程。这有点像绝对定位元素,但不像绝对定位那样强硬。
事实上,如果容器没有以这种方式响应,那将是浏览器 bug。
Aslett 的原始 clearfix 文本中也缺少从 Holly Hack 借用的反斜杠。我认为您的 CMS 正在吃掉反斜杠转义字符。(编辑:已修复。)
此外,Aslett clearfix 块上面的段落写道:
…但是,Aslett 的原始 clearfix 没有使用
:before
,只使用了:after
。:before
被整合到随后的 Micro Clearfix 和 Combinator Clearfix 迭代中。(编辑:也已修复。)我仍然使用 2009 年 Mr Coyer 发布的“group”版本!
感谢您提醒我们网页历史中的重要元素!但我想补充几点
浮动元素不会包含在块中,甚至会穿透源代码中之后的块,这并不是“bug”,而是浮动元素按预期工作的原理(允许文本围绕它们流动)。但这在使用浮动模拟列时是不希望看到的行为。这本身就是一种 hack,但在当时,除了浮动和绝对定位之外,没有其他方法可以将事物并排水平放置在 CSS 中。所以存在一个名为“包含浮动”的问题……
…有两种方法可以解决它:使用“clear”属性,也称为clearfix,以及使容器建立新的块级格式化上下文(作为“overflow”属性、“display”更改、“float”容器本身、在 IE5-6 中通过“zoom: 1”启用“hasLayout”魔法等方面的副作用)。
这两类解决方案并不等效。它们在“clearfixed”容器如何对之前的浮动元素做出反应,以及其非浮动子元素的边距(如果存在)如何与其自身边距合并方面存在根本差异。“display: flow-root”并不是“clearfix”的替代品,虽然它解决了包含浮动的问题:您不能简单地用另一种解决方案替换它,并确保布局中的其他所有内容都像以前一样工作。
我在 Rachel Andrew 关于“display: flow-root”的帖子中分叉了一个 Codepen 演示,并对其进行了修改,使其更直观地显示两种方法(以及某些特定技术的)之间的差异:https://codepen.io/SelenIT/pen/qrORXm。希望有人觉得它有用!
为了了解
clear
修复的历史,Anne 在 2005 年关于使用overflow
的文章 [1] 可能也很重要。替代方法存在很多问题 [2]。[1] https://annevankesteren.nl/2005/03/clearing-floats
[2] https://meiert.com/en/blog/no-clearfix/
非常感谢您提供这篇文章和解释,我一直使用模板并进行了一些研究来编辑它们,但我不知道这个问题。了解这段历史很有帮助,以防我遇到这个问题,再次感谢您提供这篇文章。
谢谢。我喜欢网页历史,并了解 hack 存在的原因。我对 clearfix 感到好奇。有趣的历史。
自 2007 年以来,我已构建了近 200 个网站,从未使用过 clear fix。我不太明白为什么你需要它。我只是将所有内容都浮动起来,效果很好。
很高兴您不必遇到之前的问题,但肯定有一些设计需要打破浮动才能实现,浮动所有内容无法满足这些设计的要求。