都2023年了,不会还不知道CSS变量吧!!!

311 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情

前言

样式预处理语言(less、scss)在很早就出现变量的概念,但是本质上还是通过对应的loader编译成css,缺少灵活性

CSS3紧跟潮流也提出了变量的概念,不仅能完成同样的业务,还不需要安装loader编译,而且还可以完成一些特别的业务~~~

熟悉预处理语言的朋友其实可以对照着学习,因为CSS为了减少开发者的学习成本,所以在变量方面的设计也都参考了这些预处理语言的变量!!!

变量的声明定义

定义变量的语法:--<variableName>:variableValue,中文表达就是--<变量名称>:变量值

变量命名

变量的命名其实是很宽松的,不存在像JS变量不能数字开头的限制,只需要遵守不能包含$[^(%等字符就可以了!!!

body {
    --red: red;
    --黄色: yellow;
    --20: 20px;
    ---30_f: 30px;
}

看吧,这些奇奇怪怪的命名也都是可以的~~~

特别注意:变量是区分大小写,--red--Red代表了两个不同的变量

:root {
    --red: red;
    --Red:yellow;
}

可以把变量看做特殊的CSS属性,CSS属性所能使用的位置({}里面),也是变量所能定义的位置

变量的使用

是变量的语法:var(<variableName>,<declarationValue>),中文表达就是var(变量名称,默认值)

意思就是,如果在根据给定变量名找不到对应的变量值时,就使用第二个参数的值

:root {
    --color: red;
}
div {
    color: var(--color, yellow); /* 字体颜色为red,如果(--red)变量不存在,那么就使用参数二(yellow) */
}
变量不能用来拼接属性名称
:root {
    --color: "color";
}

div {
    var(--color): yellow;	/* 不能用来拼接属性名称 */
}

这里和预处理语言是不一样的,并不能把变量使用在属性名称上~~~

使用场景

变量值的类型可以是字符串、数字、CSS合法属性值中任意一种~~~

可以把CSS变量理解为JS中的常量,在定义时,类型和值就已经固定,不能通过其他方式进行类型转换

字符串类型

一般只会使用在CSS属性值是字符串的地方(字符串拼接、content属性、字体名称等......),其实就是有""出现的地方

:root {
    --hellow: "你好!";
    --content: var(--hellow)"信息";
}

div::after {
    content: var(--content);
}

这个时候你可能就会想,在colorfont-sizemargin等属性值上使用就不可以吗?

答案是肯定的,不能!!!

div {
    color: red;
    font-size: 20px;
    margin: auto;
}
div {
    color: "red";			/* 无效使用 */
    font-size: "20px";		/* 无效使用 */
    margin: "auto";			/* 无效使用 */
}

可以看到这些CSS的属性值不支持字符串,所以千万不要乱用哦!!!!

这个时候你可能又会想,字符串类型可以和字符串类型拼接,那么可以字符串类型可以和其他类型拼接吗?

答案是还是不可以!!!,无论是数字类型还是css合法属性值都不能和字符串类型拼接~~~

:root {
    --20: "100";
    --f20: var(--20)px;
}

div {
    font-size: var(--f20);	/* 无效使用 */
}
数字类型

数字类型使用场景就一个,和px拼接使用

:root {
    --20: 100;
}

div {
    font-size: var(--f20)px;
}

这可能是最容易想到的写法吧~~~

但是现实是残酷的,这么写是错的!!!!

这里回忆一下字符串类型讲过,字符串类型只能和字符串类型拼接,其实数字类型也是一样的,不能和其他类型直接拼接~~~

:root {
    --20: 100;
}

div {
     font-size: calc(var(--f20) * 1px);
}

数字类型也仅有这样一种使用场景

CSS合法属性值

这是最常用的属性值,值也就是平时使用CSS的属性值~~~

:root {
    --color: red;
    --margin: 10px 20px;
}
范围和权重

这里讨论一下变量的使用范围和权重,也可以理解为变量的作用域

:root {
    --color: red;
}
div {
    --color: yellow;
}
.content {
    --color: violet;
}

nav {
    --Ncolor: black;
}

*{
    color:var(--color);
}
<body>
    <div>我是红色,我使用全局变量的值</div>
    <div class="content">这里的颜色是是紫色</div>
</body>

从上面可以得到下面结论:

  • :root是顶层作用域,在内部定义的变量可以在全局使用

  • 变量的使用也是符合CSS层级关系的,如果通过层级一层一层往上找,没有找到这个变量的定义,也就不能使用这个变量了;(比如无法在div.content中使用Ncolor变量)

  • 变量定义也是遵守CSS的权重规则,并且规则和CSS属性一样,并且也可以通过!important提升变量定义的权重;(比如在divdiv.content都定义了color变量,但是在使用时,会首先选择div.content定义的变量)

CSS和JS交流

现在有一个需求:用户可以自定义页面主题,不同主题有不同的配色

一般朋友都会选择写很多不同主题的类,然后切换不同的类就可以了,但是这样做其实很难扩展其他主题色

这个时候就可以使用CSS变量啦,只需要修改:root定义的变量值就就可以了

var root=document.querySelector(":root")

//设置
root.style.setProperty("--bg-color","red")