CSS自定义属性以--开头在:root声明实现主题色管理,通过var()引用,支持动态切换和JS读写,但需注意作用域、大小写敏感及fallback机制。
直接在 :root 里声明颜色变量,所有后代元素都能通过 var(--primary-color) 引用。它不是“运行时变量”,而是级联生效的静态声明,修改后浏览器自动重绘。
--primary-color,不能写成 primary-color 或 $primary
:root 是全局;写在 .dark-theme 内就只对该类及其子元素生效--gap: 1rem、--shadow: 0 2px 4px rgba(0,0,0,0.1) 都行:root {
--primary-color: #4a6fa5;
--text-color: #333;
--bg-color: #fff;
--border-color: #e0e0e0;
}靠 class 切换 + 层叠覆盖是最轻量、最可控的方式。不要试图用 JS 批量改几十个 style.setProperty,维护成本高且易出错。
.dark 类下,和 :root 同级或嵌套均可,但确保选择器权重不弱于原声明prefers-color-scheme 媒体查询可自动响应系统偏好,但手动开关仍需靠 class 控制document.documentElement.classList.toggle('dark'),无需操作每个变量:root {
--primary-color: #4a6fa5;
--bg-color: #fff;
}
.dark {
--primary-color: #6b8cbc;
--bg-color: #1e1e1e;
}
body {
background-color: var(--bg-color);
color: var(--text-color, #333); / 提供 fallback /
}
var(--color) 有时不生效?常见失效场景不是语法写错了,大概率是作用域、拼写或 fallback 导致的“静默失败”。浏览器不会报错,只会回退到默认值或继承值。
--PrimaryColor 和 --primarycolor 是两个不同变量.card 里定义了 --text,但 p 标签不在 .card 内,就读不到color: var(--text-color) 如果变量未定义,会变成 color: inherit,看起来像“没变”@keyframes 或伪元素 ::before 中使用时,确保父元素已声明该变量(伪元素继承父级自定义属性)JS 操作的是计算后的样式值,所以读取要用 getComputedStyle,写入用 style.setProperty。注意:只能改元素自身的 style,影响范围取决于你操作的对象。
getComputedStyle(document.documentElement).getPropertyValue('--primary-color')
document.documentElement.style.setProperty('--primary-color', '#ff6b6b')
cardEl.style.setProperty('--accent', 'gold')
setProperty 影响性能function setTheme(theme) {
const root = document.documentElement;
root.style.setProperty('--primary-color', theme.primary);
root.style.setProperty('--bg-color', theme.bg);
root.style.setProperty('--text-color', theme.text);
}CSS 变量真正难的不是声明,而是设计变量命名层级和 fallback 策略——比如 --color-brand-primary 和 --color-ui-border 要不要拆开,var(--color-text, #333) 的 fallback 是写死值还是另一个变量,这些决定了后期换肤时改几处。