CSS 变量
简介
声明一个 CSS 自定义属性:
- 以
--
前缀开始命名,即--自定义属性名
,注意自定义属性名严格区分大小写,--on
和--ON
是不同的 - 放置在一个
{}
花括号内
:root {
--primary-color: #0055fe;
}
还可以使用 JavaScript 的
style.setProperty()
动态注册一个CSS自定义属性document.documentElement.style.setProperty('--primary-color', '#0055fe')
可以通过
getPropertyValue
获取到一个 CSS 自定义属性的值getComputedStyle(document.body).getPropertyValue("–color")
引用一个 CSS 自定义属性:
- 使用
var()
函数引用var()
函数可以提供回退值,var(<custom-property-name> [, <declaration-value> ]?)
,var()
函数引用了未定义或手误写错了自定义属性名称时,会有一个降级处理
:root {
--primary-color: #0055fe;
}
div {
color: var(--primary-color);
}
var()
函数可以进行嵌套:.box { background-color: var(--primary-color, var(--black, #f36)); }
特性
1、var()
函数引用一个未定定义的变量不会导致样式解析错误
- 引用未定定义的变量不会阻止样式加载、解析或渲染,只是会使用回退值,或者无回退值时,会回退到属性的继承或初始状态
2、自定义属性在接受值时非常宽容
自定义属性可以接受非常多的值:
:root {
--brand-color: #990000; /* 十六进制 */
--transparent-black: rgba(0, 0, 0, 0.5); /* 函数 */
--img: url('./images/angles-top-left.svg'); /* 函数 */
--spacing: 0.66rem; /* 各种单位的值 */
--visibility: hidden; /* 属性值 */
--my-name: "w3cplus"; /* 字符串 */
--index: 1; /* 数字 */
--s: 50%; /* 百分比 */
}
不过不能简单的将数字和单位粘在一起使用,比如不能将 24
和 px
组合在一起获得 24px
,不过可以通过将原始数字乘以带有单位的数值来实现
3、无效变量
当一个自定义属性的值是 initial
时,var()
函数不能使用它进行替换。除非指定了一个有效的回退值,否则会使声明在计算值时无效
当这种情况发生时,属性的计算值要么是属性的继承值,要么是它的初始值,分别取决于属性是否被继承,就像属性的值被指定为 unset
关键字一样
4、 !important
可以在变量之内或之外使用 !important
修饰符
将 !important
应用于自定义属性会使得难以覆盖自定义属性的值
实践
1、重复值复用
:root {
--v-padding: 20px;
padding: 30px var(--v-padding) 50px var(--v-padding);
}
2、拆分值
.element {
background-color: hsl(120 50% 50% / 1);
}
可以像下面这样来描述一个颜色:
.element {
background-color: hsl(
var(--h, 120)
var(--s, 50%)
var(--l, 50%)
/
var(--a, 1);
)
}
在不同状态下,可以很方便的调整颜色,比如在暗黑模式下,整体颜色暗20%
@media (prefers-color-scheme: dark) {
.element {
--l: 20;
}
}
主题色
如定义一个默认色
与动画结合
使用 @keyframes
创建了一个 breath
动效(呼吸灯效果),并且在 .walk
和 .run
上都使用了这个 breath
动效,只不过是在时间上做了一些调整,.walk
的持续时间比 .run
的长。事实上,.walk
执行 breath
的速度较慢,但它更需要一个更深的呼吸灯效果:
虽然 CSS 自定义属性给 CSS 带来很多优势,但也有一定的缺陷,比如说,CSS 自定义属性在 @keyframes
规则中使用时并不能被动画化:
使用 @property
可以改变这种现象
JS 控制 CSS 伪元素
通过 js 改变元素的 CSS 自定义属性,伪元素使用 CSS 自定义属性的方式可以实现 JS 控制 CSS 伪元素样式
if else 实现
可以通过自定义属性 --i
,当:
--i
的值为1
时,表示真(即打开)--i
的值为0
时,表示假(即关闭)
来看一个小示例,有一个容器 .box
,希望根据自定义属性 --i
的取值为 0
或 1
做条件判断:
- 当
--i
的值为1
时,表示真,容器.box
旋转30deg
- 当
--i
的值为0
时,表示假,容器.box
不旋转
:root {
--i: 0;
}
.box {
/**
* 当 --i = 0 » calc(var(--i) * 30deg) = calc(0 * 30deg) = 0deg
* 当 --i = 1 » calc(var(--i) * 30deg) = calc(1 * 30deg) = 30deg
*/
transform: rotate(calc(1 - var(--i)) * 30deg));
}
.box.rotate {
--i: 1;
}
通过上面的例子,结合 calc 运行,可以实现一些 if else 的效果: