必须带功能前缀(如--color-、--space-)并禁用裸名,按作用域分层管理,组件级变量挂载到根节点而非:root,变量管值不管状态,须设fallback且统一注入。

大型项目里 CSS 变量命名不规范,不是“不好看”的问题,而是直接导致样式污染、调试崩溃、协作卡点——比如改一个 --button-bg,结果弹窗、表单、第三方组件全跟着变色,DevTools 里根本找不到变量定义在哪。
为什么不能用裸名(如 --color、--sm)?
裸名等于放弃作用域控制。不同模块、不同人写的 --color 各自覆盖,构建后 source map 失效,getComputedStyle 查到的值来源不可追溯。Bilibili-Evolved 强制用 --be-、--ui- 前缀,不是为了语义漂亮,是让变量能被 grep 定位、被 IDE 跳转、被 CI 检查。
-
--color这类名在多人协作中必然撞车;--color-text-primary才能明确表达“文本主色”,且和 JS 中的textPrimary变量名形成语义隔离 - 一级前缀必须按功能维度划分:
--color-、--space-、--radius-、--shadow-,而不是按组件或状态(如--button-、--hover-) - 禁止出现
--main-color这类模糊名——“main”指谁的 main?暗色模式下还 main 吗?
组件级变量怎么隔离,避免全局污染?
所有组件级变量必须挂载到组件根节点上,不能塞进 :root。否则按钮的 --size-md 和卡片的 --size-md 一旦值不一致,就变成隐式耦合。
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
- 写法示例:
.ui-button { --ui-button-bg: var(--color-surface-default); },而不是在:root里定义--button-bg - 组件类名与变量前缀要映射但不套 BEM 语法:
.button--large对应--ui-button-size-large,而非--ui-button--large - Modifier 类(如
.button--disabled)仍保留,它只负责切换状态 class,变量只管注入值:.button--disabled { background-color: var(--ui-button-bg-disabled); }
fallback 和注入时机为什么必须统一?
没 fallback 的 var(--color-text-primary) 在变量未定义时会回退为 inherit 或 initial,造成样式断裂;而分散注入(有的在 :root,有的在组件里)会让 fallback 行为不可预测。
立即学习“前端免费学习笔记(深入)”;
- 所有
var()必须带 fallback:color: var(--color-text-primary, #333) - 全局变量统一注入到
:root;组件变量统一注入到组件根节点(如.ui-button),且仅限该选择器作用域生效 - vanilla-extract 等工具推荐用
createThemeContract结构化定义,强制生成kebab-case变量名,并支持 TypeScript 类型推导,避免拼写错误
最常被跳过的细节:布尔型变量(如 --is-hovered)是反模式。CSS 变量适合管“值”,不该管“状态”。状态靠 class 控制,变量只负责把对应值注入进去——这个边界一旦模糊,就会催生一堆难以维护的 :hover { --is-hovered: 1 } 套路。

















