变量是CSS预处理器存在的主要原因之一。为某样东西设置变量的能力,比如颜色,在CSS中让变量保持一致,可DRY,并且易于改变是很有用的。出于相同原因,也可以使用原生CSS变量(“CSS自定义属性”)。但有一些重要的差异应该清楚。
一个简单的预处理器变量使用示例如下:
$brandColor: #F06D06;
.main-header {
color: $brandColor;
}
.main-footer {
background-color: $brandColor;
}
That was the SCSS variant of Sass, but all CSS preprocessors offer the concept of variables: Stylus, Less, PostCSS, etc.
这是Sass的变体SCSS,但所有的CSS预处理器都提供了变量的概念:Stylus, Less, PostCSS等等。
上面的代码在浏览器中什么也不做。浏览器不会理解声明并抛出它们。预处理器需要编译成CSS才能被使用。这段代码将被编译为:
.main-header {
color: #F06D06;
}
.main-footer {
background-color: #F06D06;
}
这才是有效的CSS代码。变量是预处理器语言的一部分,不是CSS本身的语言。一旦代码编译,变量就会消失。
原生CSS也已开始支持CSS变量,称为“CSS自定义属性”。允许直接在CSS中使用变量。无需编译。
一个简单的CSS自定义属性使用示例如下:
:root {
--main-color: #F06D06;
}
.main-header {
color: var(--main-color);
}
.main-footer {
background-color: var(--main-color);
}
这两个demo实现的是完全相同的效果。我们可以定义一次颜色值,多处使用。
那么,应该使用哪个呢?
为什么使用原生CSS自定义属性?
- 无需使用预处理器就能使用它们
- 可级联。可以在任何选择器中设置变量以设置或覆盖它的当前值。
- 当它们的值改变(例如媒体查询或其他状态)时,浏览器根据需要重绘。
- 可以在JavaScript中读取和操作它们。
关于级联,这有一个简单的例子:
:root {
--color: red;
}
body {
--color: orange;
}
h2 {
color: var(--color);
}
所有<h2>
的颜色都会变成orange
,因为所有的<h2>
都是<body>
的子级,具有更高的适用特性。
甚至可以在媒体查询中重新设置变量,并让这些新值在它们使用的地方级联,这对于预处理器变量来说是不可能的。
看这个例子,它使用媒体查询改变了用来建立简单网格的变量:
Rob Dodson在CSS Variables: Why Should You Care?一文中提倡使用CSS的自定义属性
预处理器的变量有一个主要的缺点,它们是静态的,不能在运行时更改。增加在运行时更改变量的能力不仅打开了诸如动态应用主题的大门,同时对响应式设计及补充将来的CSS特性的潜力具有重大影响。
他引入了一个demo,使用JavaScript改变样式。然而它并不直接在元素上改变样式,而只是在运行时重置了一些CSS变量。
Wes Bos也有一个这样的demo:
注意我在这里忽略了一堆关于CSS自定义属性的东西。你可以设置回退。你可以使用calc()
。有很多很酷的技巧可以使用。看下面的作业部分:
为什么使用预处理变量?
- 从大处说:没有继承浏览器支持的注意事项。它们编译成正常的CSS。
- 从小处来说:必要时可以把一个值的单位去掉。
可以同时使用它们
有相当多令人信服的理由同时使用这两个。你完全可以使用CSS预处理输出CSS自定义属性。Ivan Ivanov创建了一个demo,使用了CSS自定义属性的语法,并通过Sass,使得输出的代码可以回退。
我倾向于认为,一旦我们可以使用CSS自定义属性而不必担心浏览器支持,我们只是使用它们来做所有的变量处理。我们仍可能为了其他的方便而使用预处理语言,但原生的CSS处理变量似乎也很不错,值得一试。
CSS自定义属性的浏览器支持情况
这份关于浏览器支持的数据来自Caniuse,它也报告了这个特性处于W3C的候选推荐状态中。
作业时间:提升
1) 看Lea Verou的CSS Variables: var(--subtitle);
她覆盖了大量的实际应用和一些特技,比如控制变量级联和一些陷阱。
2)看 David Khourshid的CSS的反应动画
David分享的想法是,将CSS变量和DOM事件结合使用就能用不多的代码实现一些很棒的UI动画。看他的幻灯片([从#26开始)(http://slides.com/davidkhourshid/reactanim#/26)),真棒。
3) 看一看Harry Roberts的用自定义属性打造务实、实用和先进的主题
他的文章解释了使用CSS变量会令改变网站的用户主题容易得多。
4) 看Roman Komarov的 CSS变量的条件
尽管经常被讨论,但CSS中没有逻辑门(例如 @if (true) { }
)。我们有时候会用checked
来伪造,但这取决于DOM。Roman shows off a trick一文(译文)中介绍了通过在变量上使用0
或1
,然后使用calc()
)来模拟布尔逻辑。
本文根据@CHRIS COYIER的《What is the difference between CSS variables and preprocessor variables?》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:https://css-tricks.com/difference-between-types-of-css-variables/。
如需转载,烦请注明出处:http://www.w3cplus.com/css/difference-between-types-of-css-variables.html