功能类名应表达语义角色而非视觉特征,如.btn--primary、.card__title;表现类名含red、large等CSS值词,易失效且不可复用;Modifier须可枚举、有明确定义;is-/has-状态类描述逻辑状态,与样式无关。

功能类名必须能回答“这是什么”
功能类名描述组件的语义角色,不是它长什么样。比如 .card 是功能类,因为它代表“一张卡片”,不管它圆角还是直角、有无阴影;而 .card-rounded 就是表现类——它只说“这个卡片是圆角的”,但没说明它是不是卡片,也不具备复用前提。
常见错误是把视觉特征当功能:写 .btn-red 而不是 .btn--primary;写 .header-large 而不是 .header--expanded。这类命名一旦设计变更(比如品牌色换蓝),就得全局搜替换,且无法跨项目复用。
-
.btn--primary表示“主操作按钮”,语义稳定,换主题也能沿用 -
.card__title表示“卡片里的标题”,不依赖字体大小或颜色 -
.is-disabled是状态类,属于通用功能层,和具体组件解耦
表现类名往往带尺寸/颜色/位置等视觉词
只要类名里出现 red、large、left、bold、shadow 这类直接对应 CSS 属性值的词,基本就是表现类。它们容易随 UI 变更失效,也不该作为组件的主干类名存在。
这类命名适合用于工具类(utility class),比如 .text-center、.m-4,但不能混进 BEM 的 Block/Element/Modifier 结构里——BEM 的 -- 修饰符只接受语义化变体,不是样式快照。
立即学习“前端免费学习笔记(深入)”;
- ✅ 合规:
.btn--small(小尺寸是预设变体,有明确交互含义) - ❌ 违规:
.btn--12px、.btn--bg-blue、.card--with-shadow - ⚠️ 边界情况:
.card--compact看似表现,但若团队约定它代表“信息密度高”的交互模式,就可接受
Modifier 值必须可预测、可枚举
BEM 的 -- 修饰符不是自由发挥区。它的取值应来自有限集合,且每个值在项目文档或代码注释中有明确定义。比如 .btn--primary 和 .btn--secondary 是设计系统中确认过的两类按钮行为,不是开发随手写的 --v2 或 --new-style。
如果一个修饰符需要靠开发者“猜”它对应什么效果,或者每次新增都要翻查 Figma 或问设计师,那它大概率是表现类混进了功能层。
- 检查方式:搜索
btn--*,看是否所有匹配项都能在设计规范里找到对应条目 - 重构建议:把
.card--dark-mode改成.card--inverted(语义不变,脱离实现细节) - 警惕嵌套表现:
.card__title--h2是错的——h2是 HTML 标签,不是组件状态
State 类(is-/has-)天然属于功能层
is- 和 has- 开头的类名是 BEMS 中的状态层,它们描述组件当前所处的逻辑状态,与视觉无关。比如 is-hidden 不等于 display: none,它可能触发动画、影响 ARIA 属性、或改变 JS 行为。
这类类名可以跨 Block 复用,正说明它抽象的是功能状态,不是外观。你不会看到 is-red 或 has-large-font ——这些违反了状态类的设计初衷。
-
is-loading:组件正在请求数据,可能显示 spinner 或禁用交互 -
has-error:表单字段校验失败,影响提示逻辑和 focus 流程 -
is-collapsed:折叠态影响子元素渲染、键盘导航顺序等
--mobile、--desktop、--full-width。它们表面像功能,但背后绑定的是断点或布局策略——一旦响应式逻辑调整,这些类名就失去意义。真正该用的,是 --condensed、--expanded、--fluid 这类表达组件内在行为的词。


















