bem一致性靠编译时校验、scss语法约束和模块边界声明三者锁死;block名须全局唯一且带语义前缀,element仅单层嵌套禁用html标签名,modifier须表意图而非样式,scss禁用空格嵌套后代选择器。

在CSS框架开发中,BEM一致性不是靠命名约定文档维持的,而是靠编译时校验+SCSS语法约束+模块边界显式声明三者共同锁死的。不设防,三个月后就会出现 card__footer__copyright 和 card--loading 这类违规写法。
block 名必须全局唯一且带业务域前缀
框架里不能出现孤立的 button、card、modal 这类泛化 block 名——它们注定会和其他团队、第三方库冲突。真实项目里,button 会被拆成 ui-button(基础控件)、form-button(表单专用)、cart-button(购物车上下文),前缀即归属。
- 允许:
ui-button、product-card、checkout-step - 禁止:
button、card、step(无上下文,无法定位维护人) - 注意:前缀不是“加个字符串”,而是语义锚点;
ui-表示可跨业务复用,cart-表示强耦合,二者不可混用
element 只能单层嵌套,且禁止使用 HTML 标签名
SCSS 编译器不会报错,但 card__content__title 这种写法等于主动放弃 BEM 的作用域隔离能力。它暴露的是结构误判,而非命名疏忽。
- 正确:
card__title(title 是 card 的直接视觉组成部分) - 错误:
card__content__title(content 不是语义元素,只是容器;若需复用,应升为card-content块) - 禁用:
card__img、button__span(用image、label等语义名词替代) - 后果:一旦 DOM 结构微调(比如
img换成picture),样式就断链,且无法被工具自动检测
modifier 必须表达意图,不能描述样式结果
button--primary 合法,button--bg-blue 违规——前者绑定变量 --color-primary,后者绑定具体值,品牌色一换就得全局搜索替换,且无法推断其业务含义。
- 允许:
input--disabled、tab--active、product-card--on-sale - 禁止:
button--padding-12、text--fs-16px、icon--size-24 - 状态类建议分离:
is-disabled、is-loading(纯 JS 控制,不参与样式逻辑) - 多个 modifier 并列写:
button button--primary button--disabled,而非button--primary--disabled(后者破坏工具链提取逻辑)
SCSS 中必须禁用空格嵌套生成后代选择器
这是最隐蔽也最致命的一环。.card { &__title { .icon { } } } 编译后是 .card__title .icon,它把样式和 DOM 位置强耦合,一旦 icon 被抽离或复用,样式立即失效,且 BEM 工具无法识别这种越界依赖。
- 只允许:
&__title、&--horizontal、&__button--loading - 绝对禁止:
&__title .icon、&__item li a、& .header - 替代方案:需要控制子节点样式时,优先用属性选择器如
[data-role="close"],或提升为独立 block - 检查手段:grep 项目中所有含空格的选择器,90% 都是 BEM 破坏点
真正难的不是写对第一个 ui-button__label,而是在第 37 个组件、第 12 次迭代、三人并行开发时,仍能确保没人写出 button__icon__spinner 或 card--bg-gray ——这需要 lint 规则、CI 检查、以及把 BEM 当作编译约束而非风格指南来对待。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











