CSS 自定义属性(CSS 变量)

CSS 自定义属性的定义、作用域、回退值、主题化方案及与 JS 的交互。

#tech / dev / frontend #resource / css #type / concept #status / growing

[!info] related notes

CSS 自定义属性(CSS 变量)

定义

CSS 自定义属性(也叫 CSS 变量)是以 -- 为前缀的属性,通过 var() 函数引用。它们可以被继承、被覆盖,是 CSS 中实现动态主题和减少重复值的核心机制。

基本语法

/* 定义 */
:root {
  --color-primary: #1890ff;
  --spacing-md: 16px;
  --font-size-base: 14px;
}

/* 使用 */
.button {
  background: var(--color-primary);
  padding: var(--spacing-md);
  font-size: var(--font-size-base);
}

作用域与继承

CSS 变量遵循 CSS 的继承规则:子元素会继承父元素的自定义属性值。

:root {
  --theme-color: blue;
}

.card {
  --theme-color: green; /* 仅在 .card 及其子元素生效 */
}

.card .title {
  color: var(--theme-color); /* 绿色 */
}

.other {
  color: var(--theme-color); /* 蓝色(继承自 :root) */
}

变量是运行时解析的,改变值后所有引用处立即生效。

回退值

var() 支持第二个参数作为回退值:

.element {
  /* 如果 --my-color 未定义,使用 red */
  color: var(--my-color, red);

  /* 回退值可以是另一个变量 */
  background: var(--custom-bg, var(--default-bg, #f5f5f5));
}

动态主题化

CSS 变量最强大的应用场景是主题切换:

/* 亮色主题 */
:root {
  --bg-color: #ffffff;
  --text-color: #333333;
  --border-color: #e0e0e0;
}

/* 暗色主题 */
[data-theme="dark"] {
  --bg-color: #1a1a1a;
  --text-color: #e0e0e0;
  --border-color: #444444;
}

/* 组件只引用变量,不用关心具体主题值 */
.card {
  background: var(--bg-color);
  color: var(--text-color);
  border: 1px solid var(--border-color);
}

切换主题只需修改根元素的属性:

document.documentElement.setAttribute('data-theme', 'dark')

与 JavaScript 交互

读取变量

// 获取计算后的值
const primary = getComputedStyle(document.documentElement)
  .getPropertyValue('--color-primary')
  .trim()
// 返回例如 "#1890ff"

设置变量

// 修改变量值
document.documentElement.style.setProperty('--color-primary', '#ff4d4d')

// 删除变量
document.documentElement.style.removeProperty('--color-primary')

在 JS 中动态计算

// 根据窗口大小动态调整间距
function updateSpacing() {
  const spacing = window.innerWidth < 768 ? '8px' : '16px'
  document.documentElement.style.setProperty('--spacing-md', spacing)
}
window.addEventListener('resize', updateSpacing)

与预处理器变量(Sass/Less)的区别

CSS 自定义属性Sass/Less 变量
运行时是(浏览器解析)否(编译时替换)
动态修改可以(通过 JS 或媒体查询)不可以
作用域基于 DOM 继承基于文件/块作用域
媒体查询可以在媒体查询中重新定义不行
浏览器支持现代浏览器全支持编译为普通 CSS
/* 媒体查询中覆盖变量 */
:root {
  --spacing: 16px;
}

@media (max-width: 768px) {
  :root {
    --spacing: 8px;
  }
}

边界

  • 变量名区分大小写:--myColor--mycolor 是不同的变量
  • 变量值不能作为属性名或选择器的一部分:var(--prop)-size 不会变成 font-size
  • 变量值是字符串,不能直接用于 calc() 以外的数值运算(需要配合 calc() 使用)
  • var() 只能用在属性值中,不能用在媒体查询的条件中
/* 不行:变量不能用于媒体查询条件 */
@media (min-width: var(--breakpoint)) { }

/* 可以:变量可以用于 calc */
.element {
  width: calc(100% - var(--sidebar-width));
}

一句话记忆法

CSS 变量用 -- 定义、var() 引用,支持作用域继承和运行时修改,是实现动态主题的核心工具。

创建于 2026/5/27 更新于 2026/5/27