Just Writing CSS 的禅意
我想说这是未来,但我们已经在做了。
不喜欢 CSS 已经成为一种时尚。有很多原因导致这种情况,但归根结底是:CSS 不可预测。如果你从未有过调整样式规则却意外破坏了某个你认为完全无关的布局的经历——通常是在你试图发布的时候——那么你要么是新手,要么比我们其他人更优秀的程序员。
因此,JavaScript 社区撸起袖子开始干活了。在过去几年里,出现了大量旨在使 CSS 行为良好的库,统称为CSS-in-JS。
你可能没有意识到的是,**CSS 的最大问题无需使用 CSS-in-JS 即可解决**。没有这些问题,编写 CSS 不仅仅是可以忍受的——它是令人愉快的。而且你无需找到 CSS-in-JS 引入的额外问题的解决方案。
本文绝非旨在批评 CSS-in-JS 社区所做的辛勤工作。它是 JS 生态系统中最活跃的角落之一,每周都会涌现出新的想法。相反,我的目的是说明为什么基于单文件组件和真实 CSS 的替代方法如此令人愉悦。
CSS 的最大问题
CSS 中的所有内容都是全局的。因此,针对某一部分标记的样式往往会影响到其他部分。正因为这样,开发人员经常诉诸于疯狂的命名空间约定(不是“规则”,因为它们很难执行),这主要增加了患上 RSI 的风险。
当你与团队合作时,情况会变得更糟。没有人敢触碰其他人编写的样式,因为通常不清楚它们在做什么,它们应用于哪些标记,以及如果你删除它们会发生什么灾难。
所有这些的后果是追加式样式表。无法知道哪些代码可以安全地删除,因此,即使在相对较小的项目中,也常常使用另一种更具体的样式来撤消某些现有样式。
单文件组件改变了这一切
SFC 背后的理念很简单:你将组件编写在一个 HTML 文件中,该文件(可选)包含一个<style>
和<script>
属性,用于描述组件的样式和行为。Svelte、Ractive、Vue 和 Polymer 都遵循这种基本模式。
(在本文的其余部分,我们将使用 Svelte,这很明显。但如果使用模板语言的想法让你不寒而栗——你的恐惧是错误的,但那是另一个话题——那么只需使用 Vue,它允许你在 SFC 中使用 JSX。)
结果发生了一些很棒的事情
- 你的样式作用域限定到组件。不再有泄漏,不再有不可预测的级联。也不再需要设计用来防止冲突的长篇大论的类名。
- 你无需在文件夹结构中四处搜索来查找破坏你的东西的规则。
- 编译器(在 Svelte 的情况下)可以识别并删除未使用的样式。不再有追加式样式表!
让我们看看在实践中是什么样子。
每个代码编辑器都已了解 CSS,因此很有可能你会获得自动完成功能、代码整理、语法高亮显示等等——所有这些都无需额外的 JS 导致疲劳的工具。
而且因为它确实是 CSS,而不是某些驼峰式大小写到处都是引号的冒牌货,所以我们可以利用“在开发者工具中调整,然后粘贴回源代码”的工作流程,我个人是离不开它的。请注意,我们开箱即用地获得了 CSS 源映射,因此你可以立即查明相关行。这的重要性难以言喻:当你在所见即所得模式下时,你并没有从组件树的角度进行思考,因此,拥有一个可靠的方法来弄清楚这些该死的样式来自哪里至关重要。如果其他人最初编写了组件,则更是如此。(我向你保证,这是提高 CSS 工作流程效率的最佳方法。如果你在没有源映射的情况下编写样式,你几乎肯定是在浪费大量时间。我知道我以前就是这样。)
Svelte 使用(也应用于受影响元素的)属性转换你的选择器来实现作用域限定。它会警告并删除任何未使用的规则,然后缩小结果并让你将其写入 .css 文件。如果这是你的爱好,还有一个实验性的新选项可以编译为 Web 组件,使用 Shadow DOM 封装样式。
所有这些都是可能的,因为你的 CSS 会被解析(使用css-tree)并在标记的上下文中进行静态分析。静态分析为各种令人兴奋的未来可能性打开了大门——更智能的优化、a11y 提示——如果你的样式是在运行时动态计算的,那么这些可能性就更加困难。我们才刚刚开始。
但是我们可以添加工具来执行 [x]!
如果你对视频的反应是“好的,但如果我们使用 TypeScript 并为每个编辑器编写插件,那么我们就可以获得所有自动完成功能和语法高亮显示功能”——换句话说,如果你认为为了实现与 CSS 的同等功能,构建、记录、推广和维护一系列辅助项目是有意义的——那么,好吧,你我可能永远不会达成一致!
我们还没有找到所有答案
话虽如此,CSS-in-JS 确实指出了某些悬而未决问题的答案
- 我们如何从 npm 安装样式?
- 我们如何重用在单个位置定义的常量?
- 我们如何组合声明?
就我个人而言,我还没有发现这些问题足以抵消上述方法的优势。你可能有一套不同的优先级,它们可能是你放弃 CSS 的充分理由。
但归根结底,无论如何你都必须了解 CSS。无论你爱它还是恨它,你至少必须学习它。作为 Web 的守护者,我们有一个选择:创建进一步加深 Web 开发学习曲线的抽象,或者共同努力修复 CSS 的不良部分。我知道我选择哪一个。