postcss-cssnext
postcss-cssnext
是一个插件的集合, 其中通过 postcss-custom-properties
插件处理自定义变量的特性, 但这个插件只能处理 :root 下的 变量
https://github.com/postcss/postcss-custom-properties#readme
css custom properties 依赖 DOM 结构
postcss 无法处理局部变量, 原因是 cssnext 的自定义变量会依赖 DOM 结构, 如 http://jsbin.com/tisucijaho/edit?html,css,output 所示
:root {
--text-color: red;
}
.component {
--text-color: blue;
}
.component .header {
color: var(--text-color);
}
.component .text {
--text-color: green;
color: var(--text-color);
}
header 并没有取 root 的 red, 而是取 .component 的 blue, 这和 sass 是不同的. sass 的 {}
可以理解为变量的局部作用域, 在编译层面可以确定这个变量的作用范围. 而 cssnext 的变量就像可继承的 css 属性, 必然依赖实际的 DOM 结构
如上面这种写法搭配如下 DOM, cssnext 中输出的是
<div class="component">
Black
<div class="header">
Blue
<div class="text">
Green
<div class="header">Green</div>
</div>
</div>
</div>
脱离这段 HTML, 在 postcss 转换的时候, 最里面的 header 的 --text-color
无法确定是采用 .component
声明的 blue, 还是 .component .text
声明的 green
而这样一段类似的 sass
$--text-color: red;
.component {
$--text-color: blue;
}
.component .header {
color: $--text-color;
}
.component .text {
$--text-color: green;
color: $--text-color;
}
输出的是
<div class="component">
Black
<div class="header">
Red
<div class="text">
Green
<div class="header">Green</div>
</div>
</div>
</div>
有另一个插件 postcss-css-variables
可以实现局部变量, 但这个插件并没有遵循 cssnext 规范: https://github.com/MadLittleMods/postcss-css-variables/issues/4, 原因就是 DOM 依赖导致实际上是无法实现的