bem难上手的根本原因在于它强制初学者提前回答三个工程化问题:组件边界、变体定义方、安全复用部分;而非单纯记忆语法。

初学者觉得BEM难上手,根本原因不是语法记不住,而是它不解决“怎么写样式”,而是在强制你提前回答三个工程化问题:这个组件的边界在哪?它的变体由谁定义?哪些部分能被其他模块安全复用?
为什么手写 __ 和 -- 会越写越混乱
新手常把 BEM 当成字符串拼接练习,看到一个按钮就硬套 btn__text--large,结果很快发现:card__title--warning 和 modal__title--error 样式逻辑重复、改一处得同步五处。这不是命名错了,是没识别出真正的“块”。
- 真正独立的块必须能脱离上下文存在——
.card可以,但.card__title不行;.title单独出现就是反模式 - 元素名必须语义化,
card__header合理,card__div-2是灾难——后者等于把 DOM 结构暴露进类名,一换标签就全崩 - 修饰符不能表达位置关系:
nav__item--in-sidebar违反原则,应拆出新块.sidebar-nav
useNamespace 类工具不是锦上添花,而是止损刚需
人工拼 my-button__icon--loading 的错误率远高于想象:拼错前缀、漏掉下划线、大小写混用——这些在编译期无法捕获,只能靠肉眼和运气。
-
useNamespace('my')返回的ns.b('button').e('icon').m('loading')把结构约束转为函数调用,错一个参数直接报错 - 前缀变更(如从
my-改为super-)只需改一处配置,而非全局搜索替换 - 配合 TypeScript,
e()参数会被限制为预设元素列表,杜绝btn__txt这类随意缩写
BEM 的“冗余类名”其实是编译层该干的活
HTML 里写满 class="card card--featured card__content card__title card__title--highlight" 确实反直觉,但这恰恰暴露了使用姿势错误。
- 真实项目中,这些类名应该由组件封装生成,比如 Vue 的
<card title-variant="highlight"></card>内部调用classnames组合,模板里只留意图 - 用 Sass 函数封装更进一步:
@include b('card') { @include e('title') { ... } },CSS 文件里看不到原始字符串 - 所谓“冗余”,本质是把设计契约(什么状态可组合、哪些元素允许修饰)从 CSS 提前到 JS/Sass 层声明,避免后期靠猜
最易被忽略的一点:BEM 的有效性不取决于你写了多少 __,而取决于团队是否对每个 --modifier 达成共识——它支持哪些参数、能否叠加、有无副作用。没有 Code Review 和设计文档兜底,再规范的命名也只是漂亮废纸。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











