CSS自定义变量需在:root中用--前缀声明,如--color-primary;var()的fallback仅在变量未定义时生效,不兼容IE;JS通过getComputedStyle读、style.setProperty写;与Sass变量应分工协作,避免命名冲突。

如何在 CSS 中定义和使用 --color-primary 这类自定义颜色变量
直接在 :root 里用 property: value 语法声明,所有后代元素都能通过 var(--color-primary) 读取。它不是预处理器变量,不编译,是浏览器原生支持的运行时机制。
常见错误是写成 color-primary: #007bff(漏掉双横线),或在非 :root 或非选择器作用域里直接声明(如写在 .btn 块内却不加选择器前缀),导致无法继承或覆盖失效。
-
:root是最常用且推荐的作用域起点,等价于html元素,确保全局可访问 - 变量名必须以两个连字符开头,如
--text-color,否则无效 - 支持级联和重定义:在深色主题下可重新给
--color-primary赋值,无需改 JS 或 HTML
为什么 var(--color-primary, #007bff) 的 fallback 有时不生效
fallback 只在变量未定义或值为 unset 时触发,**不是**浏览器不支持 CSS 变量时的兜底方案。也就是说,IE 完全不识别 var(),此时整个声明会被忽略,fallback 不起作用。
典型误用场景:想兼容 IE,就只写一行 color: var(--color-primary, #007bff) —— 这在 IE 下会丢失颜色样式。
立即学习“前端免费学习笔记(深入)”;
- 真要兼容 IE,需额外写一层降级:先写静态值,再覆盖为变量,如
color: #007bff;
color: var(--color-primary, #007bff); - fallback 不能嵌套另一个
var(),例如var(--c1, var(--c2))是非法语法 - 如果变量值是无效颜色(如
--color: none),部分浏览器仍会触发 fallback,但行为不统一,别依赖它校验输入
在 JavaScript 中读写 CSS 自定义颜色变量的实际操作
用 getComputedStyle 读,用 style.setProperty 写,注意目标元素必须是已挂载的 DOM 节点,且变量名要带 -- 前缀。
const root = document.documentElement;
// 读取
const primary = getComputedStyle(root).getPropertyValue('--color-primary').trim();
// 写入
root.style.setProperty('--color-primary', '#ff6b6b');
容易踩的坑:直接读 root.style.--color-primary 会报错;用 setAttribute('style', '...') 会覆盖整个 style 字符串,破坏其他内联样式。
- 批量更新多个变量时,建议统一用
root.style.cssText += '; --x: y; --z: w'(注意分号和空格) - 动态换肤时,避免高频调用
setProperty,可先拼好字符串再一次性写入 - SSR 场景下,
document不存在,JS 端读不到变量值,需服务端同步注入或约定默认值
和 Sass/Less 颜色变量混用时的关键区别与协作方式
CSS 自定义变量是运行时的、可被 JS 修改的、支持级联的;Sass 变量是编译时的、静态的、无作用域继承的。二者定位不同,不该互相替代,而应分工。
典型错误是把所有颜色都从 Sass 迁移到 CSS 变量,结果发现主题切换逻辑混乱——因为 CSS 变量没有命名空间,--primary 在多个组件库中容易冲突。
- 推荐做法:Sass 管“源定义”,如
$primary: #007bff;CSS 变量管“运行时映射”,如:root { --color-primary: #007bff; },由构建脚本自动从 Sass 输出 - 不要在 Sass 中用
#{--color-primary}拼接 CSS 变量名——Sass 不理解该语法,会原样输出 - 暗色模式切换时,优先用媒体查询 +
:root[data-theme="dark"]重定义变量,而不是让 JS 大量 patch 每个元素
--color-error,但值是 #e74c3c,而你的设计规范要求 #c0392b,这时候光靠覆盖 :root 不够,得靠更具体的选择器作用域或命名前缀隔离。









