漏写 & 会导致后代选择器而非 BEM 连缀类名:忘记用 & 显式拼接父名会生成 .button __text 而非 .button__text,破坏 BEM 语义;必须用 &__text、&--primary;& 在字符串插值中无效。

漏写 & 会导致后代选择器而非 BEM 连缀类名
这是最常踩的坑:在嵌套中忘记用 & 显式拼接父名,结果编译出的是空格分隔的选择器,比如 .button __text,而不是预期的 .button__text。BEM 的语义和作用域全毁了。
必须显式写出 &__text、&--primary,哪怕看起来冗余——& 是 Less 中唯一能保证连缀生成的机制。
- ✅ 正确:
&__icon→ 编译为.button__icon - ❌ 错误:
__icon→ 编译为.button __icon(后代选择器) - ⚠️ 注意:
&在字符串插值中不生效,比如@{&}__text会报错,只能用于选择器上下文
多个 Block 共享 Modifier 时,用参数化 mixin 封装 &--@{modifier}
当 .button--disabled、.input--disabled、.card--disabled 都需要同一套样式逻辑,硬写三遍 &--disabled 不仅重复,还容易漏改。
用带参数的 mixin 抽离,既保持 BEM 语义,又避免散落的重复代码:
立即学习“前端免费学习笔记(深入)”;
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
.bem-modifier(@modifier) {
&--@{modifier} {
opacity: 0.5;
cursor: not-allowed;
}
}
.button {
// ...
.bem-modifier(disabled);
.bem-modifier(primary);
}
.input {
// ...
.bem-modifier(disabled);
}
- ⚠️
@{modifier}必须配合&使用,单独--@{modifier}无效 - ? 不建议用
extend复用 modifier,它会生成冗余选择器如.button--disabled, .input--disabled,破坏 BEM 的独立性 - ? 避免跨 block 调用,比如在
.button里调用.input.bem-modifier,这会让样式归属模糊
动态 class 绑定场景下,BEM 类名 hash 化会破坏命名约定
在 CSS Modules 或 Vite/webpack 的 css-modules 模式下,.button__text 可能被编译成 _button__text_abc123,导致 JS 中通过 el.classList.contains('button__text') 失败。
这不是 Less 的问题,而是构建链路对 class 名的干预。应对方式很实际:
- ✅ 对需 JS 控制的 class,用
:global(.button__text)显式豁免模块化 - ✅ 或改用 data 属性控制状态:
data-state="disabled"+[data-state="disabled"]选择器 - ⚠️ 不要依赖
@value或变量导出 class 名——Less 不支持运行时 class 名反射
嵌套层级超过 3 层就该警惕 BEM 结构是否合理
BEM 本身不鼓励深度嵌套,因为 .block__element__subelement--modifier 已违背 “Element 应直属于 Block” 的原则。Less 的嵌套语法容易让人无意识写出过深结构。
检查你的 Less 是否在模拟 DOM 树深度,而不是表达 UI 组件关系:
- ❌ 危险信号:
.card { .header { .title { .icon { ... } } } }→ 实际应拆为.card__header、.card__title、.card__icon - ✅ 健康嵌套:最多一层 block → element,一层 block → modifier,或 element → modifier(如
.button__icon--small) - ? 用
stylelint-selector-bem-pattern插件自动拦截违规写法,比人工 review 更可靠
BEM 的关键不在语法像不像,而在每个 class 是否有清晰的职责边界——Less 只是工具,别让它替你掩盖设计模糊。

















