# CSS 变量(自定义属性)
自定义属性(有时候也被称作 CSS 变量或者级联变量)是由 CSS 作者定义的,它包含的值可以在整个文档中重复使用。由自定义属性标记设定值(比如: --main-color: black;),由 var() 函数来获取值(比如: color: var(--main-color);)复杂的网站都会有大量的 CSS 代码,通常也会有许多重复的值。举个例子,同样一个颜色值可能在成千上百个地方被使用到,如果这个值发生了变化,需要全局搜索并且一个一个替换(很麻烦哎~)。自定义属性在某个地方存储一个值,然后在其他许多地方引用它。另一个好处是语义化的标识。比如,--main-text-color 会比 #00ff00 更易理解,尤其是这个颜色值在其他上下文中也被使用到。自定义属性受级联的约束,并从其父级继承其值。
# 1-基本用法
声明一个自定义属性,属性名需要以两个减号(--
)开始,属性值则可以是任何有效的 CSS 值。和其他属性一样,自定义属性也是写在规则集之内的,如下:
element {
--main-bg-color: brown;
}
注意
注意,规则集所指定的选择器定义了自定义属性的可见作用域。通常的最佳实践是定义在根伪类 :root
下,这样就可以在 HTML 文档的任何地方访问到它了:
:root {
--main-bg-color: brown;
}
然而这条规则不是绝对的,如果有理由去限制你的自定义属性,那么就应该限制。
:root
这个 CSS 伪类匹配文档树的根元素。对于 HTML 来说,:root 表示 <html>
元素,除了优先级更高之外,与 html 选择器相同。
如前所述,使用一个局部变量时用 var()
函数包裹以表示一个合法的属性值:
element {
color: var(--main-bg-color);
}
# 2- 继承性
自定义属性会继承。这意味着如果在一个给定的元素上,没有为这个自定义属性设置值,在其父元素上的值会被使用。 这也是为什么我们定义到 :root
就可以被文档里每个元素应用到的原因之一。
<style>
:root {
--theme-color: red;
}
body {
--theme-color: green;
}
.test-p {
color: var(--theme-color);
}
</style>
<body>
<!-- 会获取到body, 更近父元素的变量 -->
<p class="test-p">ssss</p>
</body>
# 3-自定义属性备用值
element {
color: var(--my-var, red); /* Red if --my-var is not defined */
}
# 4-javascript 操作
<body>
<style type="text/css">
body {
line-height: 1.5;
}
#box {
font-size: 20px;
}
</style>
<div id="box" style="--main-color: blue">box el</div>
<script>
const el = document.querySelector('#box');
// 获取内联样式的属性值
console.log(el.style.getPropertyValue('--main-color'));
// 获取元素任意的属性值, 无论是继承的还是css定义的
console.log(window.getComputedStyle(el).getPropertyValue('font-size')); // 20px
console.log(window.getComputedStyle(el).getPropertyValue('line-height')); // 30px
// 设置css内联样式值样式值
el.style.setProperty('--main-bg-color', 'green');
</script>
</body>
# 5-用作主题切换的一种方式
一般把一些复用的样式值定义在 :root
上面, 需要切换主题时,通过js 操作修改对应的值即可。
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<style type="text/css">
:root {
--main-color: orange;
}
.box {
color: var(--main-color);
}
</style>
<div class="box">box</div>
<script>
function getTheme(el = document.documentElement, key) {
if (!el || !key) {
return '';
}
return window.getComputedStyle(el).getPropertyValue(key);
}
getTheme(document.documentElement, '--main-color');
function setTheme(el = document.documentElement, key, value) {
if (!key || !value) {
console.warn('setTheme: Please provide parameters css key and value!');
return false;
}
try {
console.log(el);
el.style.setProperty(key, value);
return true;
} catch (error) {
console.error(error);
return false;
}
}
setTheme(document.documentElement, '--main-color', 'red');
</script>
</body>
</html>