自定义属性(有时候也被称作CSS 变量或者级联变量)是由 CSS 作者定义的,它包含的值可以在整个文档中重复使用。

变量的声明

声明一个自定义属性,属性名需要以两个减号(–)开始,因为常用的$,@等定义变量的前缀已经被less、sass预处理使用了,为了保证两者不冲突,所以选择使用--,早期也有采用var-为前缀

1
2
3
:root{       
--primary-color: green;
}

这样就定义了一个自定义属性--primary-color,他和color什么的属性没什么不同,只是没有特殊含义而已。
任何值都是可以放进css变量当中例如颜色,尺寸,定位,角度,字符串,数字、甚至是一段js代码,也可以在任何地方定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
:root{
--primary-color: green;
--success-color: #87ceeb;
--warning-color: rgb(255,165,0);

--default-height: 20px;
--default-padding: 10px 20px;

--default-line-height: 1.5;
--default-opacity: .5;

--test-string: "test-string";

--test-calc: calc(100vh - 50px);
}
@media screen and (min-width: 768px) {
:root{
--primary-colo: red;
}
}
1
2
3
<body style="--color:red;">
<span style="color:var(--color)">CSS变量</span>
</div>

备注: 自定义属性名是大小写敏感的,–my-color 和 –My-color 会被认为是两个不同的自定义属性。

变量的使用

使用var函数来使用css变量

1
<div class="box"></div>
1
2
3
4
5
6
7
8
:root{
--bg-color: red;
}
.box{
background-color:var(--bg-color);
width: 100px;
height: 100px;
}


var函数还可以使用第二个参数,来表示默认值,如果使用的变量不存在,就会使用默认值

1
2
3
4
5
.box{
background-color:var(--bg-color,green);
width: 100px;
height: 100px;
}


他只会读取第一个变量的值,如果第二个参数也是用css变量,就酱紫写,同样也是可以拥有默认值的

1
2
3
4
5
.box{
background-color:var(--bg-color,var(--bg-default-color,pink));
width: 100px;
height: 100px;
}

如果几个变量的值都为字符串的时候,是可以进行拼接的。

1
2
3
4
5
6
7
:root{
--test-one: 'one';
--test-two: 'two';
}
.box::after{
content: var(--test-one)var(--test-two)
}


但是如果是数值和单位的话就不行的

1
2
3
4
5
6
7
8
:root{
--test-width: 100;
}
.box{
width: var(--test-width)px;
height: 100px;
background: red;
}


要这样用就搭配函数calc使用

1
2
3
4
5
6
7
8
:root{
--test-width: 100;
}
.box{
width: calc(var(--test-width) * 1px);
height: 100px;
background: red;
}

作用域

CSS变量,即CSS自定义属性。跟普通属性一样,CSS自定义属性的继承,优先级同样遵循CSS级联规则。一个元素上没有定义自定义属性,该自定义属性的值会继承其父元素。按照层叠关系向上查找。最终查找到根元素,也即前面例子中用到的:root选择器所定义的变量。因此,变量的作用域就是它所在的选择器的有效范围

1
2
3
<div class="box" id="box">
<div class="box-text"></div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
:root{
--primary-color: red;
}
body{
--primary-color: yellow;
}
.box{
--primary-color: blue;
}
.box-text{
background:var(--primary-color);
width: 100px;
height: 100px;
}


同样他也是优先级的 和css的优先级是相同的
行内样式>ID>类选择器>标签选择器>通用选择器
同样权重计算也是同样适用的 那同样也就是可以使用!important来提升优先级的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
:root{
--primary-color: red;
}
body{
--primary-color: yellow;
}
.box{
--primary-color: blue;
}
#box{
--primary-color: orange;
}
.box#box{
--primary-color: pink;
}
.box-text{
background:var(--primary-color);
width: 100px;
height: 100px;
}

通过js操作

读取

getPropertyValue

1
<div class="box" id="box" style="--primary-color:red;">

这种方式只能读取写在行内的css变量,并不能读取写在style标签或者外部css文件的css变量

1
2
const box = document.getElementById('box');
console.log(box.style.getPropertyValue('--primary-color'));

getComputedStyle

1
<div id="box"></div>
1
2
3
4
5
6
7
8
9

.box{
--primary-color: blue;
}
.box{
background:var(--primary-color);
width: 100px;
height: 100px;
}

使用getComputedStyle搭配getPropertyValue就可以读取了

1
2
3
const box = document.getElementsByClassName('box')[0];
const style = getComputedStyle(box);
console.log(style.getPropertyValue('--primary-color'));

读取:root内定义的

1
2
3
const root = document.documentElement;
const style = getComputedStyle(root)
console.log(style.getPropertyValue('--primary-color'));

设置

setProperty

1
2
const box = document.getElementsByClassName('box')[0];
box.style.setProperty('--primary-color','green');

删除

removeProperty

1
2
const box = document.getElementsByClassName('box')[0];
box.style.removeProperty('--primary-color');

不能使用getComputedStyle获取再进行设置或者删除,因为他是返回值的属性为只读的

兼容性

目前除ie11不兼容(现在都用edge了吧)以外,所有浏览器都支持具体支持查看->can i use
可以使用@support命令进行检测是否支持CSS变量

1
2
3
4
5
6
7
8
9
10
11
12
13
.box{
width: 100px;
height: 100px;
background: red;
}

@supports(--a: 0) {
/*支持css变量时候用下边的样式覆盖上边的*/
.box {
--primary-color: blue;
background: var(--primary-color, 'blue');
}
}

也可以使用js来检查是不是支持css变量

1
2
3
4
const isSupported =
window.CSS &&
window.CSS.supports &&
window.CSS.supports('--a', 0);