CSS 规则的作用域是全局的。放到 JavaScript 环境里说,我们写的每一条 CSS 规则,都相当于定义一个全局变量。全局变量多了,命名冲突、副作用、代码不可预测等问题就开始浮现。我们无妨把 CSS 想象成一头野马,我们所有的 CSS 命名规范上的尝试,无论是 SUITCSS 还是 BEM、SMACSS 或是其它,都是打算给 CSS 套上缰绳,但我们只是往正确的方向走了一小步。命名规范只是一种约定,如果开发者有意或无意地忽视,哪怕只是代码中的一小部分,也会给以后埋下问题。
所以我们可以看到,在 JavaScript 模块化非常成熟、各类工具齐全的今天,前端界开始往 CSS 模块化方向努力。
我最早了解到的这方面努力是 ember-component-css,比如 app/my-component/styles.css 文件内容如下:
& {
padding: 2px;
}
.urgent {
color: red;
}
构建后的 CSS 如下:
.my-component-a34fba {
padding: 2px;
}
.my-component-a34fba .urgent {
color: red;
}
构建后的 CSS 作用域不再是全局,而是限定在这个组件中,我们把 CSS 关进模块化的笼子。我们不用担心它的作用会渗透到其他代码,我们现在对我们的代码作用范围非常有信心 – 它现在更像是狙击枪,而不是手榴弹。
接下来,我在用 JSPM 时也看到模块化 CSS 的努力。
然后是 webpack 的 CSS Module mode,开发这块功能的这位甚至宣布了全局 CSS 的终结。
从上面的简单介绍中可以看到,CSS 的模块化依赖于特定工具,比如 ember-cli、webpack、jspm,如果我们不用这类工具的话,就基本无法对 CSS 做模块化,这样移植性似乎差了点,而且因为没有标准规范,所以它们的实施也不尽相同。可是这年头,不用这类工具辅助的代码,恐怕代码在可维护性、可扩展方面都会很糟糕吧。