我采访了 Thierry Koblentz,原子 CSS 的创建者,以了解导致这个流行 CSS 框架诞生的历史和背景。Thierry 现已退休,拥有丰富的 CSS 大规模编写经验,此前曾在雅虎担任前端工程师。
Thierry 因将原子 CSS 的概念推广到主流而广受赞誉,这要归功于他在 Smashing Magazine 上发表的 2013 年经典文章,“挑战 CSS 最佳实践。” 这篇文章为多年来许多流行的 CSS 库铺平了道路。在这次访谈中,Thierry 回顾了原子 CSS 的历史,并反思了其持续的遗产。

回溯到 21 世纪初,您是如何进入网页开发领域的,特别是如何以编写 CSS 为生?
Thierry Koblentz:1997 年搬到美国后,我出于兴趣自学了 HTML、CSS 和 JavaScript。
当时,我使用的是 FrontPage,并且严重依赖新闻组寻求指导。我很快成为 Macromedia 新闻组和 CSS-Discuss 的常客。早期,我宣扬 网页标准项目 的理念,并对无障碍性产生了浓厚的兴趣。多年来,前端对我来说只不过是一种爱好(我的真正工作是古董商)。我会偶尔创建一个网站,但我主要是在撰写和发布(很多)文章,分享我学到的或“发现”的技术。
这最终转化为雅虎在 2007 年打来的一个电话,询问我是否可以帮助修复和构建雅虎网站解决方案 (YSS) 网站构建器模板的样式表。工作描述:没有 HTML,没有 JavaScript,只有 CSS!而且很多!
您在雅虎的日常工作是什么样的?
TK:我多年来在雅虎的角色发生了很大变化。
我的第一份工作是为 YSS 模板创建样式表(类似于 CSS Zen Garden)。然后,在 YSS “交付” 到班加罗尔(印度)之前,我重写了 YSS 网站的标记和样式——在那里,我和我的同事一起被派去“知识转移”。
顺便说一句,正是交换样式表以创建 YSS 的不同设计的挑战迫使我们找到一种轻量级(非 js)的解决方案来动态调整视频大小;这就是我如何想出 “为视频创建内在比例。” 的方法。
在 YSS 之后,我才有机会只参与从头开始的项目(重写或其他),我越来越参与雅虎的前端工作。我编辑和创建了许多内部文档(例如 CSS 编码标准);参与招聘流程(就像我团队中的其他人一样);领导代码审查会议;举办 CSS 课程和研讨会;在 FED London 上发表演讲;帮助其他团队处理 HTML/CSS/无障碍性;参与有关技术采用的决策(例如 Bootstrap 或非 Bootstrap);创建库;审查内部文件;撰写提案;等等。
另一个细节,在我雅虎的八年里,我可能写了不到 100 行 JavaScript。如果我没有辞职或被解雇,那要感谢 朱凌燕 和 Renato Iwashima;他们在设置我的环境或处理命令行方面不知疲倦地帮助我(因为直到今天,我在这方面都很糟糕)。
当时流行的 CSS 编写实践是什么?
TK:在早期,既没有库也没有公开的方法论;那是一片蛮荒之地,什么都行:“非语义” 类、ID、CSS hacks、条件注释、框架、CSS 表达式、“JS 探测”、主要针对 Internet Explorer 设计等等。在我的旧网站上,我甚至有这样的注释
<!--MSIE5 Mac needs this comment -->
一切都是公平的,一切都被滥用了,因为我们只有非常有限的工具集,却需要做很多事情。
但是,当我加入雅虎时,情况发生了巨大的变化。来自英国的开发人员是 网页标准 的坚定支持者,我感谢他们极大地影响了雅虎的 HTML 和 CSS 编写方式。语义标记成为现实,并且遵循关注点分离 (SoC) 原则编写 CSS,达到“极致”(尽管有时对我来说过于严苛)。
YUI 拥有 CSS 组件,但还没有 CSS 框架。有一个内部 CSS 库(称为 Lego),但我从未用过它。方法论和库,如 OOCSS、SMACSS、ECSS(向 Ben 致敬)、BEM、Bootstrap、Pure 等,很快就会出现。
是什么导致了原子 CSS 的想法?
TK:在 YSS 迁移到印度之前,我的经理 Michael Montesano 询问是否有办法让班加罗尔的新团队避免编辑样式表,从而降低损坏的风险。我想 YSS 模板的经验(付费客户抱怨页面损坏)让他在进行任何样式表更改时都非常谨慎。
因此,我根据我的 ez-css 库创建了一个“实用程序表”——一个旨在让开发人员无需编辑或添加样式表中的规则即可实现其样式的表。
几年后,当时担任工程总监的 Michael 要求我仅使用实用程序类重新设计雅虎的 主页,他知道,我们再次不会负责网站维护。我们讨论了优先考虑实用程序类而非语义类,我认为当时还没有达到这样的程度。这是一个非常大胆的举动。
这项大规模的练习很快成为一个概念验证,证明了通过标记进行样式设置带来的诸多好处。它满足了许多要求,因此决定使用该“静态”样式表(称为 Stencil)重新设计雅虎我的主页产品。

在设计原子 CSS (ACSS) 期间的指导原则是什么,参与的人员有哪些?
TK:我们的 Stencil 库是静态的,它是强加/执行设计风格的绝佳工具——我们认为雅虎即将在其所有属性中采用这种风格。我们很快意识到这种情况不会发生。每个雅虎设计团队对完美的字体大小、完美的边距等都有自己的看法,我们不断收到添加非常特定样式到库中的请求。
这种情况无法维护,因此我们决定开发一个工具,让开发人员能够动态创建自己的样式,同时尊重创作方法的原子特性。这就是 Atomizer 诞生的原因。我们不再担心添加样式——CSS 声明——而是专注于创建丰富的词汇表,为开发人员提供广泛的样式选择,例如媒体查询、后代选择器和伪类等等。
使用 ACSS,开发人员可以自由使用任何他们想要的东西;因此,团队能够在使用完全相同的库时采用不同的设计风格和样式指南。并且有一些新的好处是开发人员以前从未习惯的编写样式的方式。他们不再需要担心自己的样式会破坏页面,也不需要担心编写选择器来为其组件设置样式。
ACSS 最初是为解决雅虎的问题并在雅虎的环境中工作而构建的。
参与原子 CSS 的人员有 Renato Iwashima、Steve Carlson 和我自己。Renato 和 Steve 创建了 Atomizer。
当不为大型企业编写 CSS 时,人们对 CSS 有哪些误解?
TK:2007 年加入雅虎后,我很快了解到代码库可能有多么庞大。团队遍布多个地点/时区;无数的产品;数百个共享组件;第三方代码;A/B 测试策略;扩展性要求;不同的脚本方向;本地化和国际化;各种发布周期;复杂的部署机制;大量的指标;各种遗留问题;严格的编码标准;构建流程;政治;以及更多政治等等。
其中大部分对我来说都是全新的,我不得不学习其中任何一项是否以及如何影响我编写 CSS 的方式。我开始重新审视并挑战我所有的信念,因为许多我常用的技术或方法似乎不适合,或者至少对复杂的应用程序来说适得其反。
一个“现实检验”与样式抽象有关。我们都读过文章说将M-10
类映射到margin: 10px
不是一个好主意,因为它意味着要同时编辑HTML和CSS才能更改样式。不幸的是,这就是大型/复杂项目中发生的事情
- 设计师:我想要一个
15px
的间距 - 开发人员:好的,那是
M-3x
(5px
增量) - 设计师:当然,随便!
- 开发人员:搞定!
- 设计师:实际上,
15px
有点太大,你能把它改成12px
吗? - 开发人员:不行,我们没有那个,要么是
10px
要么是15px
。 - 设计师:抱歉,这对我来说不起作用。我们可以将
M-3x
更改为12px
吗? - 开发人员:不行!我们不能那样做,因为其他团队期望
M-3x
为15px
。 - 设计师:好的,想办法解决,因为我们希望边距为
12px
。15px
太多了,10px
太少了。 - 开发人员:(去他的!)
为了预料到这样的问题,需要理解设计师在其请求背后的意图:选择的样式是由于其抽象性,例如颜色 primary,还是由于其特定值,例如我们M-3x
案例中的15px
边距?如果存在样式指南来强制执行设计原则,那么像M-3x
这样的类可能是可以的,但如果设计团队可以请求他们想要的任何样式,那么最好避免使用会导致模棱两可样式的命名约定。根据我的经验,任何模棱两可的东西都会或迟或早导致故障。
依赖文档或组件的结构进行样式设置——通过像>
或+
这样的组合器——听起来像是编写样式表的一种简洁方法,但它忽略了一个事实,即在复杂的环境中,不能假设任何特定的标记或结构是不可变的。
你认为z-index
很复杂?当你甚至不拥有组件所在的堆栈范围时,再想想。这是大型项目中需要解决的最复杂问题之一,其中团队负责页面的不同部分。我曾经写过一篇关于此的提案。
限定选择器——例如input.required
与.input.required
——看起来不错且语义化,但它会创建不必要的特异性级别——例如0.1.1与0.2.0——并阻止标记更改;通过确保不限定选择器,这两件事很容易避免。
依赖通用选择器*
来设置全局范围的样式?在一个非常大的项目中,这可能意味着你正在设置其他人的组件的样式。除非你了解他们的需求,否则不要为他人做出样式决策。
我相信你读过 ID 不好,特异性是邪恶的,但实际上,高特异性并不像你的规则创建的特异性级别数量那样成问题。在只存在两个或三个级别——比如 1.1.0、0.1.0、0.2.0——的环境中进行样式设置要容易得多,而不是在一个特异性较低但遵循“自由放任”方法——比如 0.1.0、0.1.1、0.2.0、0.2.1、0.2.2 等——的环境中进行样式设置,这通常作为大型项目中的一种防御机制,作为“沙盒”样式的一种手段。
盲目地遵循 CSS 社区的建议可能会导致不愉快的惊喜。永远不要使用尚未经过实战检验的新技术。还记得will-change
吗?并且始终了解你使用的每个样式的作用或可能触发的事件。例如,position
可以创建堆叠上下文和包含块,而overflow
可以创建块格式化上下文。
根据我的经验,深入了解 CSS 对于大型组织有效地编写 CSS 来说是不够的。在我雅虎任职期间,我经常发现自己与多年前与我观点一致的人产生了矛盾。环境是残酷的,需要非常务实才能避免许多陷阱。下次你查看大型项目的源代码时,看到一些对你毫无意义的东西,请记住尼古拉斯·扎卡斯(Nicholas Zakas)的这条推文
不要假设人们愚蠢、无知并犯错误,而是假设他们聪明、尽力而为,并且你缺乏上下文。
——尼古拉斯·C·扎卡斯(@slicknet)2013 年 2 月 10 日
雅虎内部对向原子 CSS 的过渡反应如何?
TK:ACSS 受到我们的我的主页团队的认可,但在团队之外却没有取得很好的效果。我们第一次互动是与位于圣莫尼卡的体育团队。史蒂夫和我正在进行电话会议,试图说服开发人员不遵循关注点分离原则才是正确的做法,并且它不会造成混乱。
我们向他们指出了尼古拉斯·加拉格尔最近写的一篇文章,认为“局外人”的文章会有帮助,但结果并非如此!事情进展不顺利,并且有很多摩擦。主要问题是该库由实用程序类组成,但其语法无助于缓和谈话。
我还记得与邮件团队会面,他们并没有反对原子 CSS 的想法,但希望提出他们自己的 JavaScript 方法来使用“纯”CSS 声明——因为他们无法忍受ACSS 语法。无论如何,支持该库的数据(约减少 36% 的CSS和HTML)不言而喻,因此 ACSS 最终被采用。如今,七年多后,雅虎主页、雅虎体育、雅虎新闻、雅虎财经以及其他雅虎产品仍在使用 ACSS。
为了更好地理解像 ACSS 这样的方法如何使组件可重用性至关重要的项目受益,请复制雅虎财经中组件的标记,并将其粘贴到雅虎新闻中。该组件应该看起来像是页面的一部分。这是因为 ACSS 使这些组件与页面无关。
使用括号作为类名想法是如何产生的?语法是否受到函数编写方式的启发?
TK:我们通过多次迭代确定了两组用作属性值分隔符的“候选者”:括号()
和方括号[]
。
Renato 回忆说,我们选择括号而不是方括号是因为它与 JavaScript 中的函数更熟悉,即使它以牺牲额外的Shift
键击为代价。ACSS语法旨在
- 通过Atomizer促进规则的自动生成
- 允许开发人员创建他们想要的任何任意或复杂样式
- 将学习曲线降到最低
它看起来像这样
[<context>[:<pseudo-class>]<combinator>]<Style>[(<value>,<value>?,...)][<!>][:<pseudo-class>][::<pseudo-element>][--<breakpoint_identifier>]
开发人员按照上述结构构建他们的类。核心语法基于Emmet,一个流行的工具包。我们采用了 Emmet 方法来减少特性,因为核心类是显式的属性/值对,而不是任意字符串。
我们还创建了十几个辅助类。这些应用多个样式声明,并且要么是快捷方式,例如隐藏面向视力正常的用户的內容,要么是技巧,例如使用.Cf
进行 clearfix。并且我们通过使用配置文件为开发人员提供了更多自由度,在其中他们可以创建变量——例如.PrimaryColor
——断点等等。
从未使用过 ACSS 的人会告诉你语法太奇怪了(充其量),但熟悉它的人会告诉你它在很多方面都很巧妙。
谈谈你的“挑战 CSS 最佳实践”文章是如何在 Smashing Magazine 上发表的?
TK:我之前在各种在线出版物上发表过很多文章,所以写一篇关于这种“挑战性”方法的文章是很自然的事情。
雅虎赞助了 2013 年 10 月的 Web 前端会议,Renato 在会议上安排了一个演讲来介绍我们的解决方案,而我正试图在那之前发表这篇文章。我选择不在雅虎开发者网络上发布它,因为该网站没有提供评论部分。A List Apart 无法及时发表它,但 Smashing Magazine 加快了其审查流程,以便能够在 10 月底之前发表这篇文章。
我选择一个有评论部分的出版商的做法得到了回报,因为这篇文章收到了 200 多条评论,这对我来说非常耗时——而且令人沮丧——我不得不回复它们。
现在文章中仍然保留着关于所讨论技术的免责声明,你觉得奇怪吗?即使这种技术现在在业界已经非常流行了?
TK:文章发布时,我告诉 Vitaly [Friedman,Smashing Magazine 联合创始人],我觉得那段话听起来像是某种免责声明,它会影响人们阅读文章的方式。但我并没有真正反驳,因为我理解 Vitaly 的想法。我确实觉得有趣的是,现在这种方法已经成为主流,但那段话仍然存在。
事后看来,关于 Atomic CSS,你有什么想改变的吗?
TK:总有改进的空间,尤其是在你开创了一种解决方案的时候。你无法参考别人的做法来学习他们的错误或不足之处。你没有可以借鉴的材料来改进。因此,如果我们认为自己第一次就成功了,那就太自负了。
在 Atomic CSS 方面,我们在大型项目中开发和使用“静态”样式表超过一年,积累了丰富的经验。但在动态方面——工具方面——我们并没有找到多少可以借鉴的灵感。请记住,其他库花了六年时间才效仿。
法语里有一句谚语:essuyer les plâtres.(相当于中文的“第一个吃螃蟹的人”)。
我们犯的一个错误是使用“Atomic CSS”作为 acss.io 的标题,因为正如 John Polacek 指出的那样,这造成了一些混淆。我们后来修改了这个标题。
我唯一感到遗憾的是,多年来社区是如何对待 Atomic CSS/ACSS 的,最近还发生了一件奇怪的事情,有人向我解释了“Atomic CSS”的含义。
Atomic CSS 库 [ACSS] 使用了这个名称,但我认为这具有误导性,因为你所指的功能是动态样式生成。“Atomic CSS”作为一个通用术语,指的是将小的选择器作为原子,但它们是静态的。
真是被抹去了。;)
非常感谢 Thierry 参加这次采访,并允许我们将其发布给社区。
很棒的文章!我记得读过最初的 Smashing Magazine 文章,它真的让我开始考虑其他关于 CSS 架构的观点。我不记得免责声明了……是在之后添加的吗?还是我最初只是忽略了它?
谢谢。
是的,它从一开始就在那里。实际上,根据文章当时 收到的反馈,事实证明编辑的这个做法是明智之举。
Yss 主题真是太棒了……
绝对是一个挑战,但也很有趣,可以创建和修改。
嘿,Sean!
是的,创建它们非常有趣。
希望你一切安好。
最好的祝愿。