全局样式禁用bem命名是硬性边界,因reset/base中业务类选择器会无差别覆盖所有同名类;base-类须用@extend或css变量桥接,utility类须加u-前缀且无业务语义,并与bem物理隔离。

全局样式不能用 BEM 命名,这是硬边界,不是风格偏好。
为什么 reset/base 文件里绝不能出现 .button 或 .header
浏览器不区分类名来源。一旦 reset.css 里写了 .btn { padding: 8px; },它就会无差别覆盖 Ant Design 的 ant-btn、Element Plus 的 el-button,甚至你自己刚写的 user-form__submit —— 因为所有这些元素都带 btn 类(或被 JS 动态加了)。这不是优先级问题,是架构越界。
真正该出现在 _reset.css 里的只有:
*, ::before, ::after { box-sizing: border-box; }button, input, select, textarea { font: inherit; }a { text-decoration: none; }- 禁止任何业务类选择器(
.card、.modal)、禁止伪类(.btn:hover)、禁止属性选择器(input[type="text"])
base- 类必须和 BEM 组件物理隔离
base-button 不是 BEM Block,它是基础样式契约,必须用 base- 前缀,且只通过 @extend %base-button(Sass 占位符)或 CSS 自定义属性桥接,不能直接出现在 HTML 的 class 属性里。
错误写法:<button class="base-button user-form__submit"></button> → 会导致 base-button 的 display 或 font-size 强行污染业务组件。
正确做法:
- Sass 中定义
%base-button { padding: 8px 16px; },在user-form.scss里写@extend %base-button; - 原生 CSS 中,
base-button只暴露变量:--base-btn-padding: 0.5rem 1rem;,组件内用padding: var(--base-btn-padding); - 构建时确保
base.css在所有 BEM 文件之前加载
utility 类要加 u- 前缀,且禁用业务语义
u-mt-4、u-flex-center 这类工具类可以存在,但必须满足两个条件:前缀是 u-(不是 util- 或 helper-),且名称不能含业务词(比如 u-nav-spacer 就违规)。
它们和 BEM 是平行关系,不是子集。不能写 nav__item u-mt-2 来控制间距——BEM 要求间距由 nav__item 自身的 Modifier 控制,比如 nav__item--compact。
常见陷阱:
- 把
u-hidden当成 BEM Modifier 用:nav__item u-hidden→ 应该是nav__item--hidden - 在 SCSS 中用
@extend .u-flex-center→ 工具类不支持@extend,会生成冗余选择器 - 在
components/目录下建utils/子目录 → 工具类必须放在顶层assets/styles/utils/,和 BEM 模块物理隔离
BEM 的核心约束从来不是“怎么起名”,而是“谁有权决定一个类名的含义”。全局样式一旦混入 BEM 命名,就等于把基础设施的解释权交给了某个业务模块——这个口子开了,后面所有重构都会卡在“不敢动 base.css”的死结上。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











