必须用:root定义css变量(如--primary-color: #007bff;),确保全局生效;使用时需var(--primary-color, #007bff)带后备值防崩;动态修改应调用document.documentelement.style.setproperty(),换肤时统一更新:root变量以实现自动响应。

怎么在CSS里定义和使用变量
CSS变量(Custom Properties)必须用 -- 开头,比如 --primary-color,只能在选择器作用域内生效,最常用的是挂到 :root 上让全局可访问。别写成 color: var(--primary-color, #007bff) 就完事——括号里的默认值不是摆设,它会在变量未定义或无效时兜底,避免样式崩塌。
常见错误是把变量写在普通类里却没确保父级已声明,或者误以为变量能像Sass变量一样跨文件自动继承。CSS变量不支持跨@import链继承,每个文件得自己挂到 :root 或显式继承。
-
:root中定义::root { --primary-color: #007bff; } - 组件中使用:
.btn { background-color: var(--primary-color); } - 运行时修改:
document.documentElement.style.setProperty('--primary-color', '#28a745');
换肤时该改哪一层的变量
直接改 :root 是最稳妥的,因为所有依赖它的组件会自动响应。别去逐个修改组件类名或内联style——那等于放弃CSS变量的核心优势。但要注意:如果某组件内部又用 :host 或局部 :root 覆盖了同名变量,就会屏蔽全局值,这种嵌套作用域容易漏查。
深色模式切换是个典型场景,别只靠 @media (prefers-color-scheme: dark) 做静态适配。真要支持手动切换,就得用JS控制 document.documentElement 的 style 属性,同时配合 class 切换(比如加 theme-dark 类)来触发媒体查询之外的逻辑分支。
- 推荐结构:
:root { --bg: #fff; --text: #333; } .theme-dark { --bg: #1a1a1a; --text: #eee; } - 切换时只需:
document.documentElement.classList.toggle('theme-dark'); - 避免直接 setProperty 覆盖全部变量,容易漏掉衍生色(如
--primary-light),建议整套主题变量统一管理
JS读取和更新变量的坑
getComputedStyle(document.documentElement).getPropertyValue('--primary-color') 能读,但返回的是带空格和单位的字符串(比如 " #007bff "),直接比较会出错。更新时用 setProperty 没问题,但别在循环里高频调用——每次触发都会引起样式重算,卡顿明显。
更隐蔽的问题是:变量值如果是 var(--base-color) 这种嵌套引用,getPropertyValue 返回的是原始字符串,不是计算后的结果。需要手动解析或改用 CSSStyleDeclaration 配合 getComputedStyle 多层提取。
- 安全读取:
const val = getComputedStyle(document.documentElement).getPropertyValue('--primary-color').trim(); - 批量更新更高效:
document.documentElement.style.cssText += ';--primary-color:#28a745;--bg:#f8f9fa;';
- 避免在 requestAnimationFrame 里反复 setProperty,尤其涉及动画时
变量与CSS-in-JS或框架集成的注意事项
React/Vue里用CSS变量换肤,别在组件内联style里重复定义主题变量——这会让全局变量失效。Vue的 <style scoped></style> 默认不支持 :root,得用 <style></style> 全局块;React若用 emotion/styled-components,需确保插入的CSS被挂到 document root,而不是组件shadow dom里。
Webpack/Vite构建时,CSS变量不会被提取或压缩,所以不用怕变量名被混淆。但PostCSS插件如 postcss-custom-properties 会把变量编译成静态值,关掉它,否则运行时换肤就失效了。
- 检查构建配置里是否启用了
postcss-custom-properties或类似插件 - Next.js用户注意:
styled-jsx不支持全局:root变量注入,得用<global></global>组件或外链CSS - 变量名尽量语义化(
--color-brand-primary),别用--c1这种缩写,后期维护时根本没法定位
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











