关于 CSS 中的变量和 Web 语言中的抽象

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

变量即将进入 CSS。它们已经有了实现,所以现在无法阻止了。Firefox 已在 29 版中实现了它们,而 Chrome 在 29+ 版中也已取消前缀,前提是您已启用“启用实验性 Web 平台功能”标志。

需要明确的是,无论这是否是一件好事,任何争论都无法改变现状。但我仍然认为这很有趣,所以让我们来谈谈它。

抽象的背景故事

我最近一直在做关于计算中抽象的演讲。回顾编程的历史,有几个明显的节点,我们把抽象提升到了一个新的水平。从机器代码的“1 和 0”,到汇编语言,到编译器,以及那些为我们提供像 C++ 这样的语言的抽象。

浏览器由多个部分组成,例如渲染引擎和 JavaScript 引擎。这些部分是用 C++ 编写的。因此,当我们编写 HTML、CSS 和 JavaScript 等内容时,我们又向上爬了一层抽象的阶梯。HTML、CSS 和 JavaScript 并没有取代它们下面的语言,它们位于它们之上。它们依赖于下面的层来完成它们最擅长的工作。HTML、CSS 和 JavaScript 是我们发明的语言,以便在 Web 上构建我们想要构建的东西:交互式文档。

随着时间的推移,我们希望/期望/需要 Web 平台做更多的事情。浏览器功能只会不断 *添加*,而不会 *删除*。我们吞噬这些新功能并将其发挥到极致。这使得 Web 开发变得更加复杂。我们不喜欢复杂性。它使工作变得更加困难和效率低下。

这种情况已经持续了足够长的时间,以至于我们正在迈向抽象阶梯的下一层。抽象是应对复杂性的自然武器,因此我们使用抽象来降低我们编写的代码的复杂性。

我们在 Web 上最需要的抽象是 HTML。在一个每个页面都存储为完整 HTML 文档的网站上工作将是荒谬的,从 <!DOCTYPE html></html>,你直接编辑它们。现在没有人这样做了。完整的 HTML 文档通过模板和内容块拼接在一起。

JavaScript 中的抽象是固有的。抽象的工具已经存在。变量、循环、函数等。

最后一种获得抽象处理的 Web 语言是 CSS,并且是以预处理器的形式出现的。CSS 具有极大的重复性,并且几乎不提供任何抽象工具。预处理器提供了我们迫切需要的这些东西,并拯救了局面。

流行度

这里另一个起作用的是 Web 平台的流行度。它是计算机历史上最成功的平台。与任何其他平台相比,更多的人为它构建并使用从它构建的东西。换句话说,HTML、CSS 和 JavaScript 非常成功。这在很大程度上归功于 Web 标准倡导者的努力,但那是另一个故事。

为什么像 CSS 这样的语言如此成功?因为它非常简单。选择器和键/值对。就是这样。是的,有很多小问题和细微差别。是的,真正掌握它需要很长时间。但核心语言非常简单。在十秒钟内,您可以向某人展示一段代码并解释它是如何工作的,从而使他们完全理解。

h1 {
  color: red;
}

我相信 CSS之所以如此成功,是因为它的语法易于理解、学习和教授。CSS 有很多值得抱怨的地方,但我认为早期做出了正确的语言选择。

使核心语言复杂化

就像所有语言一样,CSS 随着时间的推移而发展。与 Web 平台中的所有内容一样,它添加了新的功能。Jeremey Keith 指出@keyframes 代表了 CSS 的重大转变。首次,您可以编写没有意义的 CSS,如果代码中其他地方没有另一块 CSS,则根本无法工作。

/* This means nothing... */
.animate {
  animation: my-animation 0.2s;
}

/* ...if not for this, which could be anywhere or nowhere */
@keyframes my-animation {
  to { color: red; }
}

正如 Jeremy 所说

因此,CSS 变量(或自定义属性)并不是 CSS 背后设计原则的墙上的第一个裂缝。为了混淆我的隐喻,这条滑坡始于 @keyframes(也许还有 @font-face)。

给定的 CSS 代码块不再保证有意义。

CSS(核心语言)正在走向完全编程化的道路。如果变量有用,那么循环也一样,对吧?我们可以开始想象一个 CSS 版本,它拥有如此强大的编程功能,以至于它不再像它最初的简单、易懂的语言。这种最初使其成功的简单性。

抽象层

我绝对不是反变量或反任何编程概念。我热爱这些东西。它们赋予我作为作者的能力,使我的工作更轻松,并让我能够做更多的事情。所有(好的)抽象层都是这样做的。那么,为什么不将这些概念保留在抽象层中,而不是改变语言的核心原则呢?

再次引用 Jeremy 的话

感谢 Sass 等预处理器,我们可以鱼与熊掌兼得。

并非所有抽象都很好

本着来回博客的精神,请允许我再次回复 Jeremy。

……并非所有抽象都是好的抽象。

他继续比较 Sass 和 Haml,宣称 Sass 很好而 Haml 不好。我大体上同意这一点。我使用过一点 Haml,但从未从中获得过太多价值,而我每天从 Sass 中获得大量的价值。我在这里有两点要说明。

Chris 为抽象本质上是一件好事进行了辩护。

这里的语境需要是“随着时间的推移”。当历史上出现这些我们向上攀登抽象阶梯的节点时,总会有语言争夺在历史上占据一席之地。开发人员争论不休(就像我们现在在 CSS 预处理器市场上看到的那样),随着岁月的流逝,“赢家”出现,拥有绝大多数的“市场份额”,如果这个术语在这里适用的话。

赢家是好事,因为它们已经证明了自己。失败者(可能是)不太好的抽象。

我的第二点是,我相信存在主要抽象和次要抽象。也许这些不是很好的术语,但我的意思是,存在一种抽象提供了作者最需要和最有价值的东西(主要抽象),然后存在提供一些小细节的抽象(次要抽象)。

如上所述,HTML 的主要抽象是存储在数据存储中的模板和内容。Haml 是一种次要抽象,为特定类型的开发人员提供了更舒适的语法。CoffeeScript 也是 JavaScript 本身抽象工具的次要抽象。

Sass(或者随着时间的推移最终会成为赢家的任何东西)是 CSS 的主要抽象。