BEM规范能避免样式冲突与性能问题:类名无空格提升匹配效率,业务前缀防止命名冲突,修饰符需语义化且不带具体值,工具链强制校验,关键在开发者持续判断元素归属与状态合理性。

因为不遵循 BEM,大型项目里改一个 padding 就可能让三个页面的按钮错位、弹窗遮挡失效、响应式断点集体失灵——这不是偶然出错,而是结构失控后的必然连锁反应。
浏览器匹配样式时,BEM 类名真能快一点?
能,但关键不是名字长或短,是有没有空格。浏览器查 .user-card__avatar--loading 是一次哈希表查找;而查 .user-card .avatar 得先找所有 .avatar 元素,再逐层往上确认父级是否为 .user-card,DOM 越深越慢。
实操建议:
- 在 DevTools → Elements → Computed → Styles 面板里直接看:有空格就是危险信号
- 构建后用
grep -r "\.[a-z]\+ \.[a-z]" dist/扫描残留的嵌套选择器 - Sass 中只允许
&__element和&--modifier写法;& .user-card__badge这种会编译出带空格的选择器,必须禁用
类名冲突不是“可能”,而是“必然发生”
多人并行开发时,.btn、.header、.list 这类泛义名被不同模块重复定义是常态。微前端下,子应用各自引入 common.css,.card 覆盖 .card 不报错,但卡片圆角突然变直、文字溢出——你得花 40 分钟定位是哪个 card 里的 overflow: hidden 被删了。
立即学习“前端免费学习笔记(深入)”;
实操建议:
- Block 名必须带业务语义前缀:
user-profile✅,profile❌;product-card✅,card❌ - 禁用
global、base、layout这类泛义词当 block 名,它们注定在第 3 个迭代时变成命名黑洞 - 用
stylelint-selector-bem-pattern或postcss-bem-linter开到error级别,CI 阶段卡住伪 BEM 提交
修饰符写错,状态就变成猜谜游戏
button--width-200px、card--top-16 这类含具体值的修饰符,换设计稿就得批量新增类;user-card--active 和 user-card__avatar--active 混用,没人能说清哪个优先级更高,更别说 JS 切换时漏掉一个类就导致视觉错乱。
实操建议:
- Modifier 只描述可枚举、稳定、业务相关的状态:
button--primary✅,button--w-200❌ - 元素级修饰符不能脱离块存在:
user-card__avatar--large✅,avatar--large❌ - 禁止在模板里手拼类名:
className={`user-card ${isLarge ? 'user-card--large' : ''}`}容易漏前缀、错连字符;改用clsx或封装bem('user-card', { large: isLarge })
真正难的不是记住三段式写法,而是每次敲下 __ 或 -- 时都得问自己:这个元素是不是它所属 Block 的固有部分?这个修饰符是不是可复用、不带硬编码值、且能被设计系统文档明确标注的状态?这种判断没法靠工具自动补全,只能靠人盯住。


















