bem 通过强制类名显式声明归属关系来切断 css 对 dom 层级的隐式依赖,而非自动减少耦合;其三段式命名(block__element--modifier)是作用域契约,要求 block 语义完整、element 为直系组成、modifier 不跨级,且 html 中必须同时存在 block 类与 element/ modifier 类才能生效。

直接说结论:BEM 本身不自动减少耦合,它靠强制类名显式声明归属关系来切断 CSS 对 DOM 层级的隐式依赖——只要写错一个 __ 或 --,或者 HTML 漏掉块级容器类,耦合就立刻回来。
为什么 .header .nav a 会随 HTML 结构一起崩
这类选择器把样式作用域绑在 DOM 路径上,不是类名上。浏览器匹配时从右往左找 a,再逐层验证父级;人脑理解却从左到右看上下文。一旦加个中间 wrapper、换掉 nav 标签、甚至只是把 header 类名改成 site-header,整个规则就失效或误命中。
更危险的是多人协作场景:.form .input 和 .search-form .input 看似无关,但若两个模块都用了 <input class="input">,CSS 里任何一条 .input 规则都会全局生效。
用 BEM 后,header__nav-link 是独立、自解释、不依赖父容器的单类名。删掉 header 容器?它照样生效(只要 HTML 里写了这个类);挪到 footer?也不影响样式逻辑。
block__element--modifier 不是语法糖,是契约
BEM 的三段式不是为了好看,而是每一段都在约束作用域边界:
-
block必须语义完整、可复用、脱离上下文仍能理解,比如product-card✅,而section-2❌、container❌ -
__element只能是 block 的**直系组成部分**,且不可脱离 block 单独存在:product-card__price合理,product-card__price__currency违规(应拆成product-card__price-currency或新 block) -
--modifier只能修饰 block 或 element 本身,不能跨级:product-card--featured✅,product-card__price--featured❌(价格本身没有“是否 featured”状态,是整张卡片有)
常见错误是把修饰符当状态开关乱挂:button__icon--hidden 看似合理,但如果隐藏逻辑由 JS 控制,实际该用 button--icon-hidden(把 icon 是否显示作为按钮的一种变体),否则调试时根本分不清是哪个模块在控制 visibility。
@at-root #{&}__element 是唯一安全的 SCSS 写法
Sass 嵌套天然产出后代选择器,.card { &__title { } } 编译结果是 .card .card__title(带空格),这等于又回到 DOM 依赖的老路。
真正有效的写法必须跳出嵌套上下文:
.card {
@at-root #{&}__header {
color: #333;
}
@at-root #{&}--loading {
opacity: 0.6;
}
}
这样编译出的才是扁平、无空格的 .card__header 和 .card--loading。漏掉 @at-root,哪怕命名全对,CSS 规则也悄悄绑定了结构。
更隐蔽的坑是:修饰符和元素必须与 block 同级定义。写成 .button { &:hover { &__icon { } } } 会生成非法类名 .button:hover__icon,浏览器直接忽略,且 DevTools 里根本搜不到这条规则。
HTML 里漏写 block 类,BEM 就彻底失效
BEM 的解耦效果最终靠人落地,工具只是校验器。最常被忽略的是:所有 BEM 元素和修饰符都必须依附于 block 类存在。
例如,<h3 class="card__title"></h3> 单独出现,没有任何问题;但如果你期望 .card__title--large 生效,就必须同时写 <h3 class="card__title card__title--large"></h3> ——漏掉基础类 card__title,修饰符就失去锚点,样式不会应用,且调试时在 Elements 面板里根本看不出缺了什么。
真实项目中,这种漏写往往藏在动态渲染逻辑里:className={clsx('card__title', isLarge && 'card__title--large')} 看似没问题,但如果 isLarge 初始为 false,首次渲染就只挂了修饰符,基础类没出来。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











