写好原生CSS的禅意
我本想说这是未来的趋势,但其实我们已经在这样做了。
讨厌CSS已经成为一种潮流。这种现象有很多原因,但归根结底是因为:CSS是_不可预测的_。如果你从未经历过调整一个样式规则却意外破坏了某个看似完全无关的布局的情况(通常发生在你准备发布的时候),那么你要么是新手,要么就是比我们其他人都要优秀得多的程序员。
于是JavaScript社区卷起袖子开始工作。在过去几年里,出现了大量旨在让CSS变得更可控的库,统称为_CSS-in-JS_。
你可能没有意识到,CSS最大的问题可以在不使用CSS-in-JS的情况下解决。没有这些问题,编写CSS不仅变得可以接受 — 而且是令人愉悦的。而且你不必去解决CSS-in-JS带来的额外问题。
本文绝不是要批评CSS-in-JS社区所做的辛勤工作。这是JS生态系统中最活跃的领域之一,新想法每周都在涌现。相反,我的目的是要说明为什么另一种方法 — 基于使用真实CSS的单文件组件 — 是如此令人愉快。
CSS最大的问题
CSS中的一切都是全局性的。因此,原本针对某个标记的样式经常会影响到其他标记。正因如此,开发人员经常求助于奇怪的命名空间约定(不能称之为”规则”,因为它们很难强制执行),这主要只会增加你患上腕管综合症的风险。
当你在团队中工作时,情况会变得更糟。没人敢动其他人写的样式,因为通常不清楚这些样式是做什么的,它们适用于哪些标记,以及如果删除它们会发生什么灾难。
所有这些的后果就是只能追加的样式表。没有办法知道哪些代码可以安全地删除,所以即使在相对较小的项目中,也经常用另一个更具体的样式来撤销某个现有的样式。
单文件组件改变了这一切
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)和静态分析。静态分析为各种令人兴奋的未来可能性打开了大门 — 更智能的优化、无障碍提示 — 这些在样式在运行时动态计算时都要困难得多。我们才刚刚开始。
但是我们可以添加工具来做[x]!
如果你对视频的反应是”好吧,但如果我们使用TypeScript并为每个编辑器编写插件,那么我们就可以获得所有的自动完成和语法高亮功能” — 换句话说,如果你认为为了达到与CSS的同等水平,建立、记录、推广和维护一系列辅助项目是有意义的 — 那么,好吧,你我可能永远也不会看法一致!
我们还没有所有的答案 — 还没有
话虽如此,CSS-in-JS确实指出了一些悬而未决的问题的答案:
- 我们如何从npm安装样式?
- 我们如何重用在单一位置定义的常量?
- 我们如何组合声明?
就我个人而言,我还没有发现这些问题会超过上述方法带来的好处。你可能有不同的优先事项,这些可能足以成为你放弃CSS的理由。
但归根结底,你必须了解CSS。无论喜欢与否,你至少必须_学习_它。作为Web的守护者,我们有一个选择:创建使Web开发学习曲线变得更陡峭的抽象,或者共同努力修复CSS的不足之处。我知道我选择哪个。