block名须带业务/团队前缀(如nc-btn)以避冲突;element禁止嵌套命名和语义冗余(user-card__avatar✅,user-card__user-card-title❌);modifier应表达稳定状态(btn--primary✅,btn--red❌);规则需通过stylelint、git hook、ci三阶校验焊死。

直接用 block__element--modifier 结构不等于落地成功——公共组件的 BEM 规则必须能跨项目复用、防手误、禁冲突,否则三个月后就会出现 btn--primary 和 button-primary 并存。
Block 名怎么定才不会和第三方库撞车
公共组件的 Block 名不是“写得像组件”就行,而是要带业务或团队前缀,且避开通用词。比如按钮不能叫 button,因为 Ant Design、Bootstrap 都用这个;也不能叫 ui-button,ui- 太泛,后续扩展性差。
- 推荐格式:
nc-btn(nc= your team / product initials),myapp-card,ds-input(ds= design system) - 禁用:
base-btn、common-card、global-header—— 这些词在 PR 里一眼就能被识别为命名失焦 - React/Vue 组件文件名小写中划线化可直接映射:
UserCard.vue→ Block 名应为user-card,不是usercard或userCard
Element 命名为什么不能嵌套、也不能带 Block 语义
看到 user-card__avatar__icon 或 user-card__user-card-title 就该立刻拦截——前者违反单层 Element 约束,后者是语义冗余。BEM 的 __ 表达的是逻辑归属,不是 DOM 深度。
-
user-card__avatar✅:avatar 是 user-card 的一部分,不可脱离存在 -
user-card__avatar-icon✅:把 icon 视为 avatar 的视觉变体,仍属同一层级 -
user-card__avatar__icon❌:生成的选择器无法被stylelint-selector-bem-pattern通过,CI 会报错 -
user-card__user-card-title❌:title 已足够表达用途,“user-card-”前缀重复,且一旦抽成独立text-headingBlock,迁移成本翻倍
Modifier 怎么写才不会变成“样式开关”陷阱
修饰符不是 CSS 属性的拼音缩写。写 btn--red、card--big 或 input--12px 看似省事,实则把设计决策锁死在类名里,换主题/响应式/无障碍时只能全局搜索替换。
- 正确方向:用稳定、可枚举的状态或意图,如
btn--primary、input--error、card--compact(compact 是一种明确的布局变体,非临时尺寸) - 禁止出现:
--v2、--new、--mobile(位置/设备不是状态)、--dark-mode(应由顶层theme--dark控制,而非每个组件自己实现) - 叠加规则:多个 modifier 平级并列,顺序无关,但建议按“类型→状态→交互”排:
btn btn--primary btn--disabled btn--loading,不写btn--primary-disabled
怎么让规则真正“焊死”在开发流程里
靠文档和 Code Review 拦不住每天几十次的 class 编写。必须让错误在保存、提交、构建三阶段就被卡住。
- 本地编辑器:配置
stylelint+stylelint-selector-bem-pattern,规则设为"componentName": "^[a-z][a-zA-Z0-9]+(-[a-z][a-zA-Z0-9]+)*$",自动标红.Btn、.card_title、.header-nav - Git Hook:用
husky在 pre-commit 跑npx stylelint "**/*.{css,scss}",失败则中断提交 - CI 流程:PR 构建时强制校验,任何
__后多于一个单词、--后含数字/大写/下划线,全部拒绝合并 - 禁止在 JS 中硬编码类名:
className="user-card__title"是反模式;统一用封装函数,如cn('user-card', 'title', { 'user-card__title--highlighted': isHighlighted })
最常被忽略的一点:公共组件的 BEM 规则必须包含“例外白名单”,比如图标类 icon、加载骨架 skeleton 这类原子级元素,允许不带 Block 前缀——但必须全团队书面约定、写进规范文档,并在 stylelint 中显式放行,否则工具链一视同仁反而阻碍落地。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











