必须为css自定义属性强制添加作用域+功能双级命名空间前缀,如--ui-button-color,禁止裸名--primary等;变量仅允许在:root或组件根节点声明;所有var()须带fallback;布尔态和主题开关类变量属反模式。

大型项目里直接用 --color 或 --sm 这类裸名定义 CSS 自定义属性,等于在 DevTools 里主动放弃溯源能力——你改完变量,连它被谁用了、在哪注入的都查不到。
为什么裸名变量在审查中必然失败
代码审查不是看“有没有变量”,而是看“变量是否可定位、可推演、可收敛”。裸名如 --primary 或 --gap 在多人协作中会立刻触发三重问题:
- 来源不可知:多个组件都可能声明同名变量,
var(--primary)到底取的是:root的、还是.card上的、或是某个第三方库注入的?审查时无法静态判定 - 语义断裂:一个
--gap是指内边距、网格间距,还是动画时间?没有上下文,光靠名字无法判断用途 - 覆盖失控:下游组件用
!important强行覆盖裸名变量,或通过更高 specificity 的选择器重设,审查时根本看不出是设计意图还是补丁行为
必须强制带命名空间前缀
所有自定义属性必须以作用域 + 功能两级前缀开头,格式为 --{scope}-{type}-*。这不是风格偏好,是审查可落地的前提:
-
--color-、--space-、--radius-、--shadow-是合法一级功能前缀;--main-color、--btn-padding是非法模糊名 - 组件级变量必须挂载到组件根节点,用
--ui-button-而非--button-,避免污染全局或被其他模块意外继承 - 禁止跨层嵌套命名:不接受
--ui-button__icon-size(BEM 元素语法不适用于 CSS 变量),应为--ui-button-icon-size - 变量名与类名形成弱映射即可,不要强绑定层级:
.button--large对应--ui-button-size-large,而非--ui-button--large
审查时重点盯这三类反模式
在 PR 中看到以下写法,应直接拒绝并要求重构:
-
--is-hovered、--is-open等布尔型变量:CSS 变量管值不管状态,状态切换必须靠 class 控制,变量只负责提供opacity、transform等具体值 -
--theme-dark这类“主题开关”变量:它本身不输出值,只是个中间标识,实际样式仍需靠 JS 或媒体查询驱动,审查时无法验证其有效性 - 未设 fallback 的
var(--color-text):必须写成var(--color-text, #333),否则变量未定义时样式彻底失效,审查要确认每个var()都有兜底 - 在非 :root 或组件根节点上随意声明变量:比如在
.button__label里定义--text-color,导致该变量生命周期和作用域完全不可控
变量注入点必须统一且显式
审查时要确认所有自定义属性只在两个位置注入:
-
:root:仅用于真正全局、跨主题、跨组件的原子变量,如--color-text-primary - 组件根节点(如
.ui-button):仅用于该组件内部可变的样式参数,且必须在组件 CSS 文件顶部集中声明,不能散落在各个选择器里
任何在 .ui-button__icon 或伪元素里用 style="--x: y" 动态注入的行为,都属于审查红线——它绕过了静态分析,也破坏了变量作用域契约。
最易被忽略的一点:命名空间前缀不是加个字符串就完事,它必须和构建产物、IDE 搜索、团队文档对齐。比如 --be- 前缀一旦选定,VS Code 的全局搜索 --be- 就必须能准确定位全部变量定义,否则审查就失去意义。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











