bem不拖慢开发,拖慢的是“半套bem”——写法松散、工具没跟上、团队没对齐边界;真按规则来,盲写类名比猜命名快得多。

直接说结论:BEM不拖慢开发,拖慢的是“半套BEM”——写法松散、工具没跟上、团队没对齐边界。真按规则来,盲写类名比猜命名快得多。
为什么手写card__title会卡住?不是记不住,是边界模糊
你停顿的那一刻,往往在纠结:card__footer--sticky该挂哪?是card--sticky还是card__footer--sticky?有没有和card--compact冲突?这些犹豫全来自缺乏显式边界。
- Block 必须对应物理目录(如
src/components/card/),所有以card开头的样式只能放这里 - Element 名不能脱离 Block 独立存在,
__title永远只出现在card__title中,不会单独叫title - Modifier 只表达状态(
--hover合法),不描述样式(--blue违规)
stylelint-selector-bem-pattern怎么配才真能帮你盲写
默认配置只校验格式,header__logo和logo都能过,但后者可能是另一个 Block,混用就破坏隔离。
- 必须注册项目中所有 Block 名(如
['card', 'button', 'search-bar']) - 设
allowMultipleDashes: false,否则button--primary--loading不报错,而 BEM 明确禁止修饰符链式叠加 - 配合
no-descending-specificity,阻止写.card__header { .card__title { } }——这种嵌套会让盲写失效
React/Vue 动态类名别拼字符串,用函数封装
手拼className={`card ${isFolded ? 'card--folded' : ''}`}表面正确,实则埋雷:变量名改错、条件漏写、大小写不一致(CARD--folded),CSS 就静默失效。
- 统一用
clsx或封装bem('card', { folded: isFolded }),所有输出都基于同一 block 名生成 - 禁止在组件内硬编码带
__或--的字符串,连'card__body'都不行——它必须由函数动态合成 - Vue 的
:class同理::class="[bem('card'), bem('card', { folded: isFolded })]",不是['card', isFolded && 'card--folded']
BEM调试时最常被忽略的一点
getComputedStyle()返回的是最终计算值,不反映原始 BEM 类名。比如button--large设了padding: 16px,你查getComputedStyle(btn).padding只看到"16px",完全看不到它来自哪个类——这是最大盲区。
这意味着:你无法靠 JS 运行时反推样式归属,也不能靠它验证某个 Modifier 是否生效。调试动态切换的 Modifier(如card--loading),优先用 DevTools “Elements” 面板实时观察 class 列表变化,而不是读getComputedStyle。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











