CSS 自定义属性(CSS 变量)
CSS 自定义属性的定义、作用域、回退值、主题化方案及与 JS 的交互。
#tech / dev / frontend
#resource / css
#type / concept
#status / growing
[!info] related notes
- 所属 MOC: CSS MOC
- 相关概念: css-selector, CSS MOC
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() 引用,支持作用域继承和运行时修改,是实现动态主题的核心工具。