CSS变量必须定义在组件根选择器(如.card)而非:root,命名须带组件前缀(如--card-bg),禁止裸名或用途绑定名;Web Components需:host{--card-bg:inherit}显式透传,回退值禁用嵌套var()且须为静态值。

直接在组件里声明 --color-primary 或 --spacing-md 是错的起点——变量失控、主题失效、第三方组件不响应,全因没把「定义位置」和「使用边界」对齐。
变量必须定义在组件根选择器,而非 :root
全局 :root 适合品牌主色、基础字号、断点这些真正跨组件复用的值;组件专属配置(如卡片背景、按钮圆角、模态框阴影)得绑定到组件自身容器上。否则改一个变量,所有用它的组件全跟着变,根本谈不上“可配置”。
-
.card { --card-bg: #fff; --card-border-radius: 8px; }—— 子元素写background: var(--card-bg)才能精准继承 - HTML 内联更可控:
<div class="card" style="--card-bg: #f8f9fa; --card-shadow: 0 2px 6px rgba(0,0,0,0.08);"> - 别在
:root里写--card-bg,也别在子元素里重复声明同名变量——这等于覆盖外部传入值,变成硬编码
命名必须带组件前缀,禁止裸名或用途绑定名
变量名不是越短越好,而是要让人一眼看出作用域和语义。裸名如 --primary、用途绑定名如 --btn-bg-hover 都会破坏扩展性:前者容易冲突,后者无法复用(同一颜色可能用于文字、边框、阴影)。
- 正确:
--card-bg、--card-shadow-sm、--badge-text-color - 错误:
--bg(太泛)、--btn-hover-bg(绑定状态+组件,失去组合能力) - 基础 Token 可用语义前缀:
--color-surface、--space-md,但它们只出现在:root,组件内只引用,不重定义
Web Components 和 Vue/React 中变量透传必须显式声明
CSS 变量不会自动穿透 Shadow DOM 或深层嵌套结构。浏览器按层叠规则取值,不“猜测”你想要哪个父级的变量。
立即学习“前端免费学习笔记(深入)”;
- Web Components:
:host { --card-bg: inherit; }是必须写的,漏掉就等于关了门 - Vue 的
<style scoped>不影响变量作用域,变量仍需在父容器(比如<div class="card">)上声明 - React 中若用
className="card",就得确保 CSS 文件里有.card { --card-bg: #fff; },否则var(--card-bg)解析为空
回退值不能嵌套 var(),且必须是静态值
color: var(--text-color, var(--fallback)) 在 Safari 15.6 以下直接失效——浏览器不支持嵌套 var() 作为回退值。这不是兼容性补丁能解决的问题,是语法限制。
- 安全写法:
color: var(--text-color, #333);或color: var(--text-color, black); - 如果真需要多级 fallback,得靠 JS 注入或构建时预处理,不能依赖运行时 CSS 解析
- 别在回退值里写
!important,它会锁死后续覆盖,违背变量“可配置”的初衷
最易被忽略的一点:变量值类型必须匹配目标属性。写 --height: 200(漏单位)或 --gap: auto,浏览器直接忽略整条声明——这种错误在 DevTools 里看不出报错,只表现为样式不生效。


















