必须用 :root 声明主题变量,因其语义准确、优先级高且能稳定透传至 shadow dom 和 vue/react 组件;避免写在 html 或 body 中,以防 web components 或 下变量失效。

必须用 :root 声明,别写在 html 或 body 里
浏览器把 :root 当作 CSS 作用域顶层,语义准确、优先级高,且在 Shadow DOM 和 Vue/React 组件中能稳定透传变量。写成 html { --primary: #007bff; } 看似可行,但遇到 Web Components 或 <style scoped></style> 时,子组件可能读不到变量,导致主题失效。
每套主题单独一个 :root.xxx 规则块
通过给 添加 class(如 theme-dark、theme-blue)来切换主题,而不是靠 JS 动态重写全部变量值——更轻量、无 FOUC、可被 @media 复用。
-
:root定义默认主题(浅色) -
:root.theme-dark覆盖深色变量,不重复声明未变的项(比如--color-secondary可沿用) - 多主题同理,
:root.theme-high-contrast单独定义高对比度变量即可 - 避免嵌套写法如
.theme-dark :root—— 这是无效语法,整条规则会被浏览器忽略
变量命名要语义化,别用 --blue-500 这类具象名
用 --color-primary、--color-bg、--color-text 这类名称,换主题时只需改值,不用改组件样式。一旦写成 --blue-500,换成紫色主题就得全局搜索替换,极易漏掉或误改。
- 推荐统一前缀,比如
--theme-primary,降低和第三方库(如 Ant Design 的--ad-primary-color)冲突风险 - 值建议用十六进制或
hsl(),别用命名色(blue),否则 JS 无法读取数值,后续做动画或深色模式计算会卡住 - 不要在
:root中嵌套引用变量,例如--color-text: var(--color-primary);—— 部分旧版 Safari 解析失败
每个 var() 必须带合法回退值
不是“写了回退就万无一失”,而是变量未定义、拼写错误或被 JS 清空时,回退值才生效。漏掉它,颜色可能变成透明或黑色,UI 直接崩。
- 写法必须是
color: var(--color-text, #333);,第二个参数得是合法 CSS 颜色值 -
unset、initial不是颜色,不能当回退值用 - 伪元素(
::before)、表单控件(input::placeholder)、SVG 内联属性(fill)都得显式加var(),漏一处,换主题时那块就卡死 - 按钮的
:hover、:focus状态也得用变量,否则悬停色永远不变
var();容易被忽略的是 SVG 图标、第三方图标字体、以及 JS 动态插入的内联样式——它们不会自动继承主题,得手动补全。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











