CSS变量
简介
大型文档或应用程序(甚至是小型的)可以包含相当多的CSS。CSS文件中的许多值都是重复数据;例如,一个网站可能会建立一个配色方案,并在整个网站中重复使用三到四种颜色。更改这些数据可能很困难,而且很容易出错,因为它们分散在CSS文件中(可能跨越多个文件),而且可能不适合“查找-替换”。
CSS变量系统引入了一系列由开发者定义的自定义属性(统称为自定义属性)和 var()
函数,这些自定义属性允许开发者将任意值赋给具有作者选择名称的属性, var()
函数允许作者随后在文档其他地方的其他属性中使用这些值。这使得读取大文件变得更容易,因为看起来任意的值现在有了信息丰富的名称,并且使编辑这样的文件变得更容易,更不容易出错,因为只需在自定义属性中更改一次值,并且更改将自动传播到该变量的所有使用中。
兼容性

如图所示,移动端基本所有系统自带浏览器都支持CSS变量。
使用语法
CSS中原生的变量定义语法是:--*
,变量使用语法是:var(--*)
,其中*
表示我们的变量名称。变量名称不能包含$,[,^,(,%
等字符,普通字符局限在只要是“数字[0-9]”“字母[a-zA-Z]”“下划线_”和“短横线-”这些组合,但是可以是中文、日文或者韩文(允许但不建议使用非字母命名
)。例如:
:root {
--bg-color: #F8F8F8;
}
body {
background-color: var(--bg-color);
}
CSS变量使用完整语法
CSS变量使用的完整语法为:var( [, ]? ),用中文表示就是:var( <自定义属性名> [, <默认值 ]? ),例如:
:root {
--bg-color: #F8F8F8;
}
body {
color: var(--text-color, #333);
}
变量的作用域
:root { --color: purple; }
div { --color: green; }
#alert { --color: red; }
* { color: var(--color); }
<p>我的紫色继承于根元素</p>
<p>我的绿色来自直接设置</p>
<div id='alert'>
ID选择器权重更高,因此阿拉是红色!
<p>我也是红色,占了继承的光</p>
</div>
变量作用域和DOM绑定,如果是全局变量采用:root { --color: purple; }
形式来声明,所有的样式里面都可以使用。
div { --color: green; }
局部使用,可以当作是局部变量覆盖全局变量,也可以当作是div的层级优先级更高。会覆盖掉全局的变量值。
CSS变量不合法的缺省特性
请看下面这个例子:
body {
--color: 20px;
background-color: #369;
background-color: var(--color, #cd0000);
}
// 请问,此时<body>的背景色是?
A. transparent B. 20px C. #369 D. #cd0000
答案是A。
解析:这是CSS变量非常有意思的一个点,对于CSS变量,只要语法是正确的,就算变量里面的值是个乱七八糟的东西,也是会作为正常的声明解析,如果发现变量值是不合法的,例如上面背景色显然不能是20px,则使用背景色的缺省值,也就是默认值代替。千万不能想当然得认为等同于 background-color:20px
,这也是为什么上面要强调CSS默认值的使用仅限于变量未定义的情况,并不包括变量不合法。
CSS变量的空格尾随特性
body {
--size: 20;
font-size: var(--size)px;
}
// 请问,此时<body>的font-size大小是多少?
A. transparent B. 20px C. #369 D. #cd0000
如果你以为是20px就太天真了,实际上,此处 font-size:var(--size)px
等同于 font-size:20 px
,注意:20后面有个空格。所以,这里的 font-size
使用的是 <body>
元素默认的大小。因此,就不要妄图取消就使用一个数值来贯穿全场,还是使用稳妥的做法:
body {
--size: 20px;
font-size: var(--size);
}
或者使用CSS3 calc()
计算:
body {
--size: 20;
font-size: calc(var(--size) * 1px);
}
CSS变量的相互传递特性
就是说,我们在CSS变量定义的时候可以直接引入其他变量给自己使用,例如:
body {
--green: #4CAF50;
--backgroundColor: var(--green);
}
CSS变量的值如果发生变化,引用这个变量的变量值也会发生变化,意思就是发生联动。这样就非常的方便。例如下面的例子,只需要修改一个 --columns
的值就可以达到响应式的目的。
.box {
--columns: 4;
--margins: calc(24px / var(--columns));
--space: calc(4px * var(--columns));
--fontSize: calc(20px - 4 / var(--columns));
}
@media screen and (max-width: 1200px) {
.box {
--columns: 3;
}
}
@media screen and (max-width: 900px) {
.box {
--columns: 2;
}
}
@media screen and (max-width: 600px) {
.box {
--columns: 1;
}
}
特别鸣谢
本文90%以上内容摘抄自简书作者:ryanWSJ的文章《CSS3变量的使用方法》。
参考资料:CSS Custom Properties for Cascading Variables Module Level 1
参考资料:CSS3变量的使用方法