应在 :root 中定义语义化颜色变量(如 --text-default),通过 var() 在属性中调用;避免在简写属性中误用,JS 用 setProperty 动态修改,注意兼容性与过渡效果。

怎么在 :root 里定义颜色变量
直接在 :root 里用 --color-primary 这种命名写 CSS 自定义属性,所有后代元素都能继承访问。别写在某个 class 或组件里,否则作用域受限。
常见错误是把变量塞进 body 或某个 wrapper,结果子组件用 var(--color-primary) 时取不到值——:root 是文档根节点,等价于 html 元素,必须从这里挂。
-
:root中定义的变量是全局的,但不会自动“生效”,只是声明,得靠var()主动引用 - 变量名建议用语义化前缀,比如
--text-default、--bg-surface,别用--blue-500这类纯色值命名(后期换主题难维护) - 支持级联和覆盖:可在不同媒体查询或主题 class 下重定义同一变量,比如
.theme-dark :root { --text-default: #e0e0e0; }
为什么 var(--x) 在 background-color 里不生效
最常踩的坑是把 var(--color-bg) 直接丢进 background 简写属性里,而该变量值不含单位或函数格式(比如只写了 #fff),但 background 会尝试解析整个字符串为 background-image / background-position 等组合,一旦格式不匹配就静默失败。
正确做法是明确指定属性,比如用 background-color;或者确保 var() 返回的是完整合法的背景声明(含 url() 或渐变函数)。
- 错误写法:
background: var(--bg-main);(当--bg-main是#f8f9fa时看似能用,但换为linear-gradient(...)就崩) - 推荐写法:
background-color: var(--bg-main);或background: var(--bg-main) no-repeat center;(保证变量值与属性预期格式一致) - 调试技巧:浏览器开发者工具里看计算样式,如果显示
var(--x)没展开,说明变量未定义或拼写错误
如何让 JS 动态改 root 颜色变量
JS 不能直接改 :root 的 CSS 规则,但能通过 document.documentElement.style.setProperty() 修改根元素的内联 style,从而覆盖 :root 中的变量定义。
注意:这个操作会影响所有引用该变量的元素,且无过渡动画——如需平滑变色,得配合 CSS transition 写在对应属性上(比如 color、background-color),而不是变量本身。
-
document.documentElement.style.setProperty('--text-default', '#333');是唯一可靠方式 - 别用
getComputedStyle(document.documentElement).getPropertyValue('--x')来读取初始值——它返回空字符串,要用getComputedStyle(document.documentElement).getPropertyValue('--x')前先确认变量确实在:root中声明了 - 切换主题时,建议批量 setProperty,避免多次重排;也可提前定义好
.theme-light和.theme-dark类,在 JS 中切换 class,再在对应类下重定义变量
哪些地方不能用 CSS 变量控制颜色
CSS 自定义属性不是万能的,尤其在需要编译时确定值的地方会失效。最典型的是 @media 查询条件、content 属性里的字符串拼接、伪元素的 attr(),以及几乎所有 CSS 函数参数中无法动态插入变量(比如 rgb(var(--r), var(--g), var(--b)) 是非法语法)。
另外,SVG 的 fill、stroke 属性虽然支持 var(),但 IE 完全不支持,如需兼容老版本,得 fallback 到内联 style 或 JS 注入。
-
filter: brightness(var(--brightness));❌ 不合法,filter不接受var()作为函数参数 -
border: 1px solid var(--border-color);✅ 合法,border是简写,但var()必须返回完整颜色值(如#000或red) -
color: var(--text-primary, #333);✅ 支持 fallback,第二个参数是回退值,仅当变量未定义时生效
CSS 变量本身不触发重绘,但每次修改都会导致所有依赖它的属性重新计算。真正容易被忽略的是:变量值变更后,那些没写 transition 的属性会立刻跳变,连个淡入都没有——这不是 bug,是设计使然。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











