高复用性要求布局与表现分离:.btn-group只管flex、gap等布局逻辑,尺寸必须由.btn--lg等按钮自身修饰符显式定义,禁用em单位,避免后代选择器破坏bem单类名原则。

高复用性不是靠“多写几个类”实现的,而是靠把布局(layout)和表现(visual style)彻底分开——BEM 本身不自动做到这点,但它的命名结构强迫你做这个决策。
为什么 .btn-group--lg 会破坏按钮复用
这类写法本质是把布局容器当成了视觉单元。.btn-group只该管 display: flex、gap 和换行逻辑,不该碰 padding、font-size 或 min-height。
常见错误现象:
-
.btn-group--lg .btn这种后代选择器权重高、无法单独迁移按钮 - 按钮挪到弹窗里,
font-size被外层继承放大,0.5empadding 变形 - 团队 A 写了
.btn-group--lg,团队 B 在侧边栏用了相同类名,结果按钮尺寸被意外覆盖
正确做法:尺寸必须由按钮自身修饰符控制,比如 .btn--lg 显式声明全部尺寸属性,且禁用 em 单位。
如何用 --modifier 拆解布局与交互逻辑
一个修饰符只该表达一种意图。把横向排列和悬停高亮塞进同一个 --horizontal-hover 类,等于把 CSS 规则耦合进业务逻辑,后续无法单独关闭 hover 效果,也无法在移动端禁用横向布局。
实操建议:
- 拆成两个正交修饰符:
.list--horizontal控制flex-direction和gap,.list-item--hoverable控制:hover样式 - 禁止在
.list--horizontal里写&__item:hover—— 那是把交互硬编码进布局层 - 如果某处需要“横向但不 hover”,直接用
list--horizontal即可,无需加!important覆盖
元素名里出现 __header__title 就说明结构错了
BEM 的 __ 表示“直属子节点”,不是“任意嵌套层级”。.user-card__header__title 违反了语义分层:header 已经是块内元素,title 应属于 header 块,而不是 user-card 的二级子元素。
真正可复用的写法:
- 把 header 抽成独立块:
.header,再定义.header__title - 或让 title 直属 user-card:
.user-card__title,header 只负责包裹,不参与样式归属 - 禁止跨块通信:
.user-card__content .button是错的,必须写成.user-card__action-button
嵌套四层 DOM 不影响 BEM,但 BEM 的语义层级不能超过两层:block → element,不能再有 element → element。
修饰符失效时先查三件事
不是 BEM 失效,而是它暴露了底层问题。最常被忽略的是:
- 全局样式劫持:比如
.modal * { color: #333 }用通配符覆盖了.button--primary的文字色 - 修饰符选择器权重不足:写
.button--disabled时漏了 block 前缀,实际应为.button.button--disabled或严格约束下.button--disabled(需配合构建工具校验) - 伪类残留:
.button:hover仍生效,而.button--disabled只改了 opacity,没重置pointer-events和cursor
复杂点在于:BEM 能锁住命名,但锁不住 CSS 优先级战争、伪类状态遗漏、或 SSR 水合时类名丢失——这些得靠构建配置和运行时校验兜底。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











