直接用 & 书写 BEM 出错,因 Sass 的 & 仅代表直接父级,非任意祖先;正确做法是每个 Block 独立声明,子元素/修饰符均用 &__ 或 &-- 派生,禁止跨 Block 嵌套或重复写全类名。

为什么直接用 & 写 BEM 会出错
很多人一上来就写 &__item { },结果发现编译后样式没生效——问题常出在嵌套层级没对齐。Sass 的 & 只代表**当前选择器的直接父级**,不是“任意上层祖先”。比如你在 .header 规则里写 &__logo,它只会生成 .header__logo;但如果你在 .header-nav 里误用了 &__link,实际产出的是 .header-nav__link,而非你想要的 .header__link——这违背了 BEM 中元素必须归属明确 Block 的原则。
关键判断点:& 后面跟的 BEM 修饰符(__ 或 --)必须和它所处的顶层 Block 声明严格对应。
怎样用 & 正确生成标准 BEM 类名
最稳妥的方式是:每个 Block 的样式块以 .block 开头,所有子元素、修饰符都用 & 直接派生,不跳级、不跨 Block。
- 用
&__element生成元素类名,如.card__title - 用
&--modifier生成修饰符类名,如.card--featured - 需要组合时写成
&__element--modifier,如.card__image--rounded - 避免在嵌套中再写完整类名(如
.card__title),否则会丢失&的上下文绑定,也易导致重复或冲突
示例:
.card {
padding: 1rem;
&__title {
font-size: 1.25rem;
}
&__body {
color: #333;
}
&--compact {
padding: 0.5rem;
}
&__footer--highlighted {
background: #f0f0f0;
}
}
遇到多层嵌套时 & 还够用吗
不够。BEM 不鼓励深层嵌套,但现实里常有 .modal .modal__content .form .form__field 这类结构。此时若强行用 & 层层推进,会写出类似 &__content &__field 的错误写法——它实际编译为 .modal__content__field,完全偏离 BEM 规范。
正确做法是:每个 Block 独立声明,用命名空间隔离。即使视觉上嵌套,CSS 结构仍保持扁平。
- 把
.form当作独立 Block,而不是.modal的子集 - 它的元素仍用
.form__field、.form__label,不依赖父级上下文 - 如需限定作用域(例如只在 modal 里生效),用属性选择器或额外 wrapper 类,如
.modal.is-open .form__submit,而非靠 Sass 嵌套生成复合类名
这样既符合 BEM 的可复用性要求,也避免 Sass 编译出非法类名。
性能与维护隐患:别让 & 模糊了 Block 边界
一个常见陷阱是用 & 模拟组件继承,比如:
.button {
&__icon { ... }
&--primary { ... }
// 错误:这不是 BEM,是自定义扩展
&__icon--small { ... }
}
这里 &__icon--small 看似合理,但它模糊了“icon 是独立 Block 还是 button 的私有元素”的边界。一旦其他地方也要用小图标,你就得复制这段代码,或改用 .icon--small ——而这时你会发现,当初没把它抽成 Block,反而增加了维护成本。
真正该警惕的,不是 & 写得少,而是它被用来掩盖设计意图不清晰的问题:Block 划分是否合理?元素是否真的只属于这个 Block?修饰符是否具备语义一致性?这些比语法技巧更影响长期可维护性。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











