&符号在less中仅按规则连接选择器,并非自动拼类名的魔法开关;错误使用会破坏bem语义,产生冗余、不可组合的选择器,唯一安全写法是&__element。

Less 的 & 符号不是“自动拼类名”的魔法开关,它只是把当前选择器和父级按规则连接;用错位置或过度依赖,反而会破坏 BEM 的语义结构,生成冗余、不可组合的选择器。
为什么 &__element 是唯一安全的 BEM 拼接写法
在 BEM 中,__ 表示元素(Element),必须直接隶属于块(Block)。只有 &__title 这种写法能保证编译后是 .card__title,语义清晰、可复用、支持组合(如 .card--featured .card__title)。
-
&__title→.card__title:正确,BEM 原子性 intact -
.title(无&)→.card .title:错误,破坏 BEM,变成后代选择器,无法独立使用 -
& .title→.card .title:同上,且权重飙升,后续覆盖困难 -
&__title--large→.card__title--large:语义错误,修饰符应作用于块本身,不是元素;正确写法是.card--large .card__title
& 放错位置会导致选择器爆炸和不可维护
嵌套中滥用 & 会生成不符合 BEM 规范、难以调试的长选择器,尤其当它出现在多层嵌套内部时。
-
.card { .header { &__logo { ... } } }→ 编译为.card .header .card__logo:多出一个无意义的.header层级,既不必要又提高权重 -
.btn { &:hover { &::before { ... } } }→.btn:hover::before:合法但冗余;实际只需.btn--primary:hover::before单独定义 -
.form { &__field { &:focus { &::placeholder { ... } } } }→ 编译为.form__field:focus::placeholder:看似合理,但已跨三层(块→元素→伪类→伪元素),调试时很难定位来源
字符串拼接类名?别用 + 或插值,用 & + BEM 约定
Less 不支持运行时字符串拼接(如 "." + @name + "__" + @elem),强行用插值 @{var} 会丢失语法校验,且无法享受 BEM 工具链(如 lint、IDE 提示)支持。
- 错误示范:
@block: "card"; .@{block}__title { ... }→ 编译失败或行为不可控,VS Code 插件无法识别 - 正确路径:用
&__title配合 mixin 封装,例如:.bem-block(@name) { .@{name} { &__title { ... } &--hover { ... } } },调用.bem-block(card) - 更推荐:直接手写
.card { &__title { } &--featured { } }—— BEM 类名本就是静态契约,没必要动态生成
真正需要关注的不是怎么拼,而是谁该出现在选择器里
BEM 的核心约束不在 Less 语法,而在 HTML 结构和类名职责。一个 .card__header 元素,如果被写成 .card > .content > .card__header,哪怕用了 & 也违背了 BEM 原则 —— 它不该依赖 DOM 路径,只该依赖类名本身。
容易被忽略的是:所有修饰符(--)都必须能自由组合,而深层嵌套会让这种组合失效;比如 .card--featured.card--dark 只有在顶层定义 &--featured 和 &--dark 才有效,一旦把 dark 样式藏在 .card__header { &--dark { ... } } 里,就彻底失去组合能力。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











