CSS 自定义属性(CSS 变量)

前言

CSS 中的自定义属性非常有用,不仅用于保存 CSS 属性,还可以把复杂性和交互性抽象为更小、更易于管理的单元。本篇短文可以让你快速了解它们的工作原理和使用方法。

假设有这样一段 CSS:

h1 {
  background: goldenrod;
}

p {
  color: goldenrod;
}

.my-element {
  border: 1px dotted goldenrod;
}

它们的属性中有一个共同点,那就是属性中都包含 goldenrod 。但是这之间重复的太明显了,而且它们的属性都不一样,根本无法将它们集中定义,有什么办法可以改进?可以使用 CSS 自定义属性(也叫做 CSS 变量)来抽象和提取 CSS 样式属性,使得代码更容易管理。

:root {
  --primary: goldenrod;
}

h1 {
  background: var(--primary);
}

p {
  color: var(--primary);
}

.my-element {
  border: 1px dotted var(--primary);
}

基础知识

让我们从顶部开始,看看一些基础知识。自定义属性就像一个普通的 CSS 属性和值对:一个声明。这些声明是在 CSS 规则中定义的。

:root {
  --text-color: rebeccapurple;
}

:root 是什么选择器?它是一个伪类,表示文档树的根,大部分时间表示<html>元素。但是,如果您在自定义元素:root 将表示 shadow DOM 的根而不是<html>元素。

定义自定义属性后,您可以使用该var()函数获取它的值。这将获取 property 当前的值。结合自定义属性和 var() 函数,我们就可以在 CSS 中使用它们来合成值。

:root {
  --text-color: rebeccapurple;
}

h1 {
  color: var(--text-color);
}

默认值

如果一个自定义属性值未定义或无效,则将使用初始值或继承值。如果定义的值没有生效的话,界面看起来就会一团糟,所以这时候就有一个很好的解决办法是为该 var() 功能添加一个缺省值。

h1 {
  color: var(--text-color, royalblue);
}

这种处理就可以放置值在无效的时候样式失效了,但是如果是在不支持的自定义属性的浏览器或是使用了一个未被定义的属性的话,样式依然会渲染错误,这个元素则会取 initial 的值,所以如果在做兼容处理的话,我们不仅仅要提供一个缺省值,还需要提供一个兼容处理的方案:

h1 {
    color: royalblue;
  color: var(--text-color, royalblue);
}

权重

和 CSS 选择器及属性一样,自定义属性也有权重一说,因为这个属性也是可以被继承的,也就是说,只要在合法的元素上下文中,不管层级多深,都可以访问到它:

:root {
  --text-color: rebeccapurple;
}

h1 {
  color: var(--text-color);
}

article.colour-change {
  --text-color: seagreen;
}
<article class="colour-change">
  <h1>Change my colour by clicking the button 👇</h1>
  <button>Change colour</button>
</article>

JS 控制

在 js 中通过获取目标元素并且调用 getComptedStyle(article).getPropertyValue('--text-color') article.style.setProperty('--text-color', '#f00') 属性就可以读写 CSS 自定义属性。

const article = document.querySelector('article');
const button = document.querySelector('button');

button.addEventListener('click', (evt) => {
  article.style.setProperty('--text-color', 'tomato');
});

以上。