BEM本质是作用域隔离方案而非起名规则;它用命名替代CSS嵌套与优先级博弈,使样式严格限定在Block内,避免跨块污染,如.card__title与.header__title互不干扰。

“BEM不是起名规则,是作用域隔离方案”
直接告诉面试官:BEM本质不是为了“让类名更长”,而是用命名代替CSS嵌套和优先级博弈,把样式作用域锁死在块内。你改.card__title,不会意外影响.header__title或.list-item__title——因为它们根本不是一个Block,名字里就划清了边界。
别从“Block Element Modifier”三个词逐个解释,先说痛点:.btn .active这种写法,一旦页面里出现.modal .active,样式就串了;而.btn--active和.modal--active天然互不干扰。
怎么判断一个类名是不是真BEM,而不是“伪BEM”
看三件事:
- 有没有明确的
Block:比如.user-card合格,.section-2不合格(没语义、不可复用) -
Element名是否剥离父级语义:正确是.card__title,错误是.card__card-title(冗余)或.user-card__name(如果name在用户列表页也独立存在,它该是.user-name这个新Block) -
Modifier是否挂载合理:错误是.card__title--large,正确是.card--large .card__title(修饰符描述的是块的状态,不是元素的尺寸)
面试官问“BEM和CSS Modules比有什么优劣”,怎么答
直接说:BEM解决的是“人脑理解成本”和“跨技术栈一致性”,CSS Modules解决的是“运行时作用域”。
立即学习“前端免费学习笔记(深入)”;
PigX UI Pro 前端开发指南 - Vue 3 + TypeScript + Element Plus。当用户提到 PigX UI、PigX 前端、lgb-mgui 项目、Vue 3 企业级后台开发、Element Plus 后台开发时使用此技能。
举两个现实场景:
- 你用Vue写的
.search-form__input,和React里同名组件,只要命名一致,设计师就能一眼认出这是同一个输入框——CSS Modules做不到这点 - 第三方UI库(如
react-datepicker)输出的类名不归你管,但你可以用.form-field--date这个BEMBlock把它包一层,再用属性选择器或:global微调,而不是硬套CSS Modules的哈希
顺带提一句:BEM类名长度确实略长,但现代gzip压缩后几乎无体积影响,可忽略。
手写代码时最容易漏掉的BEM细节
不是双下划线写错,而是忘了“Modifier必须可预测”:
- 禁止用
.button--v2、.card--new这类临时标签——上线后没人记得它对应什么设计意图 - 应该用
.button--primary、.card--compact这种语义化值,哪怕换主题,只要语义不变,类名就不必动 - SCSS里慎用
&__item &__icon(中间有空格),这会生成后代选择器.block__item .block__icon,破坏BEM的扁平化原则
真正难的从来不是记住__和--,而是每次写class前,多问一句:“这个东西,离开当前Block还能不能单独存在?”

















