# 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>

MDN (opens new window)

上次更新: 1/22/2025, 9:39:13 AM