bem 中 modifier 必须独立书写、显式叠加,禁止连缀;需分维控制样式、避免属性冲突;动态添加时须配置构建工具白名单;react 中应使用受控枚举和工厂函数生成类名。

多个 Modifier 共存时,必须独立书写、显式叠加,不能合并或连缀——这是 BEM 可组合性的底线。
Modifier 必须用空格分隔,不能连写或缩写
浏览器不识别 .button--primary-loading 这类连缀名,它不是合法的 BEM Modifier,而是新造的一个 Block。一旦设计变更(比如所有 --large 按钮要统一调高行高),你得全局搜索替换,而不是改一处 CSS 变量。
- ✅ 正确:
class="button button--primary button--large button--disabled" - ❌ 错误:
class="button--primary-large-disabled"或class="button button--primary-large" - 连缀写法绕过了 BEM 的原子性,也阻断了 JS 动态条件拼接(如
classnames基于布尔值开关)
多个 Modifier 同时设置同一属性时必然冲突
根本原因不是 BEM 不支持叠加,而是 CSS 声明顺序和选择器权重没对齐。比如 .button--primary 和 .button--large 都设了 padding,后声明的规则会覆盖前一个——哪怕它们语义上完全正交。
- 确保不同 Modifier 修改的是不同维度的样式:一个管颜色(
--primary),一个管尺寸(--large),一个管状态(--disabled) - 禁止在多个 Modifier 里重复定义同一属性(如都设
background或border-radius) - 若必须覆盖(如
.button--disabled.button--loading要降低透明度),需单独写组合选择器:.button--disabled.button--loading { opacity: 0.5; }
构建工具可能误删动态添加的 Modifier
像 PurgeCSS、cssnano 这类工具默认只扫描 HTML 模板里的静态类名,button--loading 若由 JS 动态添加(如点击后插入),很可能被当成“未使用”直接删掉。
- PurgeCSS 配置中必须加入 safelist,例如:
/button--(primary|large|disabled|loading)/ - cssnano 的
mergeLonghand选项会把.button--primary.button--large压缩成单个类名,导致样式丢失,务必禁用 - 验证方式:构建后检查 dist 目录生成的 CSS 文件,确认所有需要的 Modifier 类都存在
React 中 Modifier 必须来自受控枚举,不能字符串拼接
手写 `button--${theme}` 是高危操作:theme 若为 undefined 或恶意字符串(如 "dark;alert(1)"),会生成非法类名或 XSS 风险。
- Modifier 值应限定为明确的枚举,例如:
type ButtonVariant = 'primary' | 'secondary' | 'danger'; - 用
bem工厂函数生成类名:buttonBem.m('primary'),再交由classnames统一处理 - 禁止混入字面量字符串(如
'button--disabled'),所有类名必须经styles[]查表,确保编译后哈希名正确
最易被忽略的一点:Modifier 的叠加不是“加了就行”,而是“加了之后是否仍可控”。只要有一个 Modifier 改了基础尺寸或盒模型,就可能破坏其他 Modifier 的布局预期——这得靠人工校验,工具几乎无法覆盖。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











