css变量需在:root或带类名的作用域中定义,scss中可直接用var(--var-name, fallback)读取;私有变量应加下划线前缀,主题切换须同步data-theme、localstorage及prefers-color-scheme。

直接在 SCSS 文件里用 var(--color-primary) 就能读取主题变量
React + SCSS 项目中,组件样式本身不感知外部主题变化,但 CSS 变量天然支持动态更新。只要确保变量定义在 :root 或带类名的 :root.ink\:dark-theme 等作用域下,SCSS 里就能无感使用。
关键不是“怎么写”,而是“变量在哪定义、谁负责更新”。比如 .navButton { color: var(--nav-item-color); } 这行代码永远有效——前提是 --nav-item-color 已被注入到当前生效的根作用域中。
- 别在组件内用
getComputedStyle读变量再塞进style属性,那会绕过 CSS 引擎优化,还触发重排 - 私有变量推荐加下划线前缀,如
--_nav-item-hover-color,避免和全局主题变量冲突 - 必须提供 fallback 值:
var(--nav-item-color, #007bff),否则变量未定义时样式直接失效
useTheme Hook 不该自己存状态,而应从 document.documentElement 实时读 data-theme
很多实现把当前主题存在 Context 的 useState 里,结果 document.documentElement.setAttribute('data-theme', 'dark') 改了,Context 却没更新——组件还是用旧值渲染,JS 逻辑和 CSS 样式就脱节了。
真正对齐的方式是让 Context 的值始终等于 DOM 上的真实属性值:
- Provider 初始化用
useState(() => document.documentElement.getAttribute('data-theme') || 'light') - 用
MutationObserver监听document.documentElement的attribute变更,仅过滤data-theme - 回调里调用
setState(root.getAttribute('data-theme')),保证所有useContext(ThemeContext)组件同步响应
切换主题时只改 data-theme 不够,还得同步 localStorage 和 prefers-color-scheme
用户点一下「深色模式」按钮,期望的是:页面立刻变、下次打开还是深色、系统级偏好也对齐。只改 DOM 属性,localStorage 没存,刷新就回退;不调 window.matchMedia('(prefers-color-scheme: dark)'),系统级暗色适配就断连。
一个健壮的 toggleTheme 应该做三件事:
- 执行
document.documentElement.setAttribute('data-theme', nextTheme) - 写入
localStorage.setItem('theme', nextTheme) - 手动触发
matchMedia的监听回调(如果需要模拟系统行为)或至少记录当前选择,避免与系统偏好冲突
Ant Design / MUI 等组件库开启 cssVar: true 后,变量名前缀和结构必须严格匹配
像 Ant Design 5 或 MUI 的 createTheme({ cssVariables: true }) 会把主题配置自动转成 CSS 变量,但生成的变量名不是随便起的。例如 AntD 的 token.colorPrimary 会输出为 --ant-color-primary,MUI 的 palette.primary.main 输出为 --mui-palette-primary-main。
如果你在自定义 SCSS 中想覆盖它们,必须:
- 确认组件库是否已启用 CSS 变量模式(
ConfigProvider的cssVar或createTheme的cssVariables设为true) - 查文档确认变量命名规则,不要手写
--color-primary去碰--ant-color-primary - 优先用组件库提供的
override配置项(如 MUI 的components.MuiButton.styleOverrides),而非硬覆盖 CSS 变量
变量名错一位、前缀少一个连字符,CSS 引擎就当它不存在——这种错误极难调试,因为浏览器 DevTools 里看着变量是“定义了”的,只是没被任何选择器引用。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











