css中用:root定义全局颜色变量,如--primary-color,后代元素通过var()读取;其作用域为整个html文档树,非全项目通用;支持动态主题切换、js运行时修改及继承动画。

怎么在CSS里定义全局颜色变量
用 :root 块声明,所有后代元素都能通过 var() 读取。它不是“全局”在文档外生效,而是作用域覆盖整个 HTML 文档树——这点常被误解为“全项目通用”,其实只是当前 CSS 文件 + 当前 HTML 生效。
-
:root本质是最高层级的选择器(等价于html),但优先级略高,且语义更明确 - 变量名必须以两个连字符开头,比如
--primary-color,写成-primary或primary-color都无效 - 值支持任何合法 CSS 值:颜色、长度、数字、甚至
calc()表达式,但不能是属性名或选择器 - 重复声明时,后加载/后出现的
:root块会覆盖前面的,没有“合并”逻辑
CSS变量如何实现主题切换
核心是动态替换 :root 下的变量值,而不是切换整套样式表。浏览器会自动重绘依赖这些变量的属性,比 class 切换更轻量,也比 JS 操作每个元素更可控。
- 深色/浅色主题只需两组
:root定义,用 class 控制哪组生效:html.dark :root和html.light :root - 不要用
body.dark :root——:root只匹配根元素,body上加 class 对它没影响 - JavaScript 切换主题时,改的是
document.documentElement.className,不是document.body - 变量值不支持媒体查询嵌套(如
@media (prefers-color-scheme: dark) { :root { ... } }是合法的,但不能写成:root { @media (...) { ... } })
为什么 var(--color) 有时不生效
最常见原因是作用域链中断或拼写错误,而不是浏览器不支持(Chrome 49+/Firefox 31+/Safari 9.1+ 都已支持)。
- 变量未在祖先元素(含
:root)中定义,var(--missing)直接退回到初始值(比如 color 属性会变成inherit),控制台不报错 - 大小写敏感:
--PrimaryColor和--primarycolor是两个变量 - 空格敏感:
var( --color )合法,但var(--color, #000 )末尾空格可能导致部分旧版 Safari 解析失败 - 回退值不能是另一个
var()(除非是嵌套函数,但不推荐);写成var(--c1, var(--c2))在部分浏览器中不可靠
和预处理器变量(如 Sass $color)有什么区别
CSS 变量是运行时的,Sass 变量是编译时的——这是根本差异,直接影响你能否响应用户操作实时换肤。
- Sass 变量最终被替换成静态值,打包后就固定了;CSS 变量保留在浏览器中,JS 可随时修改
document.documentElement.style.setProperty('--color', 'red') - 无法用 Sass 变量实现“用户点击按钮切主题”,除非生成多套 CSS 文件并手动切换
<link> - CSS 变量可继承、可被动画(如
transition: background-color 0.3s对background-color: var(--bg)有效),Sass 不参与运行时行为 - 调试时,浏览器开发者工具里能看到实时计算后的
var()结果,而 Sass 变量只存在于源码中
真正难的不是定义变量,而是管理变量层级和 fallback 逻辑——比如组件内想覆盖主题色,又不想污染根变量,就得用局部 :host 或 style 属性注入,这时候作用域和优先级就得算清楚。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











