按钮状态类名必须用--修饰符,如.btn--disabled;.btn-disabled或.btn_disabled会被误判为新块,破坏BEM语义,导致构建误删、DevTools无法识别状态、协作易覆盖。

按钮状态类名必须用 -- 修饰符,不能写成 .btn-disabled
直接写 .btn--disabled 才是合法 BEM 修饰符;写成 .btn-disabled 或 .btn_disabled 会被当做一个新块(block),不是状态标记。DevTools 里看不出它是临时状态,构建工具可能误删,协作时也容易被当成独立组件覆盖或重写。
常见错误现象:.btn-disabled 在 CSS 中权重和 .btn 一样,但语义断裂——它既不是块,也不是元素,更不是修饰符,纯属命名污染。
-
.btn--loading、.btn--success、.btn--error是正交的,可自由组合 - JS 添加时必须用
element.classList.toggle('btn--disabled', isDisabled),别拼字符串 - 多个状态共存时(如
.btn--disabled.btn--loading),CSS 必须显式写组合规则,例如:.btn--disabled.btn--loading { opacity: 0.6; } - 禁止嵌套写法:
.btn--primary--disabled是非法语法,BEM 不认它为修饰符
尺寸修饰符如 .btn--sm 必须完整定义所有尺寸属性
.btn--sm 不是“微调”,而是对小号按钮的视觉契约声明。它不继承父级 font-size,也不该挂到容器(如 .btn-group)上——否则破坏单类名原则,样式会随 DOM 结构变动而失效。
必须显式声明以下属性,漏掉任一都可能导致高密度场景下点击区域不足、文字截断或圆角失衡:
立即学习“前端免费学习笔记(深入)”;
-
font-size: 0.875rem(禁用em,避免被外层放大) padding: 0.375rem 0.75rem-
min-height: calc(1.5rem + 2px)(保障 WCAG 点击区域) line-height: 1.5border-radius: 0.25rem
响应式适配要和语义分离:尺寸修饰符管“设计意图”,媒体查询管“设备适配”。比如在小屏下进一步缩小:
@media (max-width: 480px) { .btn--sm { font-size: 0.75rem; padding: 0.25rem 0.5rem; } }多个修饰符共存时,class 顺序不影响样式,但影响可维护性
CSS 层叠不看 HTML 中 class 的书写顺序,只看选择器权重和源码位置。所以 .btn--primary.btn--sm 和 .btn--sm.btn--primary 效果完全一致。
但人要读代码。推荐固定顺序:btn btn--primary btn--sm btn--disabled(基础 → 语义变体 → 尺寸 → 运行时状态)。这种排列能一眼识别主导状态,也方便自动化 lint 工具校验。
- 禁止穿插写法:
btn--sm btn btn--primary容易漏加、难定位 - 所有修饰符必须用单类名选择器:
.btn--sm { },别写.btn.btn--sm { }——后者权重低,叠加时易被覆盖 - 尺寸修饰符不该碰
margin或display,那是布局职责,应交给工具类或父容器控制
加载状态必须用修饰符控制,不能靠子元素实现
加载动画属于按钮自身的临时视觉变体,不是新组件。正确做法是加 button--loading 修饰符到根元素上,所有动画、光标、图标旋转、禁用交互都通过这个类控制。
常见错误是新增子元素:<button><span class="button__loader"></span>提交</button>。这会导致两个问题:一是动画脱离按钮尺寸上下文,缩放或禁用时表现异常;二是 button:disabled 不会自动停掉子元素动画,可访问性也受损。
- 用
button--loading后,CSS 可统一处理:.button--loading { cursor: wait; pointer-events: none; } - 若需叠加效果(如 loading + disabled),必须单独写:
.button--loading.button--disabled { opacity: 0.6; } - 禁止用
button--loading--disabled这类嵌套修饰符,BEM 不支持
最常被忽略的是:修饰符名必须绑定具体 UI 表现,而不是后台返回值。写 .btn--network-error 就越界了——UI 层不该感知网络细节;.btn--error 才对,它只说明“按钮当前显示错误态”,至于为什么错,由 JS 和业务逻辑决定。


















