TAT.bizai 全局 CSS 的终结 (狗带) [译]
In 未分类 on 2015年10月22日 by view: 20,604
23

CSS 类名总是作用在同一的全局作用域里面。

任何一个跟 CSS 有长时间打交道的开发者,都不得不接受 CSS 那具有侵略性的全局特性,明显地这是一种文档流时代的设计模型。而对于今天现代 web 应用,更应该积极提出一种更健全的样式环境。

每一个 CSS 类名都有可能与其它元素产生的意想不到副作用,又或者产生冲突。更令人吃惊的是,我们的 class 的效果可能在全局作用域的互相影响下(原文这里比喻为全局唯一性战争),最终在页面上产生很少的效果或者根本没有效果。

任何时候我们改变一个 CSS 文件,我们都需要小心翼翼地考虑全局环境是否产生冲突。没有其他前端技术是需要如此之多的规范和约束,而这仅仅是为了保持最低级别的可维护性

、、、

 

但我们不能一直这样下去。是时候摆脱这种全局样式的折磨。开启局部 CSS 的时代!

“ 在其他语言,全局环境的修改需要变动的代码很少”

在 javascript 的社区中,感谢 BrowserifyWebpackJSPM,让我们的代码变得模块化,每个模块有明确的依赖及其输出的 API。然而,不知怎么的,CSS 视乎总时被忽略掉。

我们中许多人,包括我自己,一直使用 CSS 工作这么长时间,我们都没有发现缺少局部性作用域,是一种问题。因为没有浏览器厂商的重大帮助下我们也能够解决。即使这样,我们仍然需要等待着,大部分用户能使用上浏览器的 ShadowDOM 的支持。

在全局作用域问题上,我们已经使用一系列的命名规范来编码。想 OOCSSSMACSSBEMSUIT,每一个都提供着一种方式模拟健全的作用域规则,达到避免命名冲突效果。

虽然驯服 CSS 无疑是一个巨大的进步,但这些方法都没有解决我们样式表上真正的问题。无论我们选择哪个规范,我们依然被卡在全局类名上。

但,在 2015 年的四月 22 号将会发生改变。

、、、


正如我们此前的一篇文章涉及到——“Block,Element,修改你的 JavaScript 组件”—— 我们可以利用 Webpack 把我们的 CSS
作为一种 JavaScript 模块来引用。如果这听起来很陌生,去读读这篇文章会是一个 good idea,以免你错失接下来要讲的内容。

使用 Webpack 的 css-loader,引用一个组件的 CSS 如下:

乍一看,这很奇怪,我们引用的是 CSS 而不是 JavaScript

通常,一个 require 引入的应该提供一些局部作用域。如果不是,明显低会产生全局作用域的副作用,这是一种拙劣的设计。而 CSS 的全局作用域特性,却必定产生这样的副作用。

因此我们在思考

、、、

2015 年 4 月 22 日,Tobias Koppers 这位对 Webpack 孜孜不倦的代码提交者,提交了一个 css-loader 新特性的版本提交。当时叫 placeholder,而现在叫 local-scope。这个特性允许我们输出 classname 从我们的 CSS 到使用中的 JavaScript 代码。

简而言之,下面这种写法:


我们改为

看看我们导出的 CSS 是怎么样的,我们的代码大概如下:


在上面的例子中我们使用 css-loader 的定制的语法  :local(.idntifier) ,输出了两个的标识符,foo 和 bar。
这些标识符对应着 class strings,这将用在 javascript 文件中去。例如,当我们使用 React