BEM通过将归属、层级、状态硬编码进类名(如.user-card__title--small),消除对DOM结构、标签类型和嵌套深度的隐式依赖,实现样式精准作用域与跨模块隔离,改A不崩B。
因为后台系统长期迭代必然带来 DOM 结构变动、多人协作增删模块、状态逻辑膨胀——BEM 把“谁写的、在哪用、能不能动”直接刻进类名里,而不是靠猜文件路径或翻 Git 历史。
传统写法如 .user-card .title 或 .header h3 把样式生效条件藏在 DOM 层级和标签类型里。一旦把 <h3> 换成 <div role="heading">,样式静默失效;更危险的是,它可能意外匹配到另一个模块的 .title,导致改 A 崩 B。
.user-card__title 不依赖父容器、不依赖标签、不依赖嵌套深度,只认这个字符串user-card__ 能精确命中所有相关样式,不会误伤其他 .title
默认的 stylelint 对 BEM 几乎零约束。.btn-primary、.modal-close-btn 全部畅通无阻。必须手动启用插件并严格配置:
selector-bem-pattern 设为 { "componentName": "[a-z][a-zA-Z0-9]+", "styleType": "bem" },拒绝大驼峰和下划线开头ignoreSelectors 加上 ["/^..+:(hover|focus|active|disabled)/"],避免误报伪类fix: true —— 语义纠错没法靠机器做,自动修复可能生成 .card__content__title 这种非法嵌套stylelint --config .stylelintrc.js src/**/*.css,不通过就阻断合并常见错误是把具体值塞进类名:btn--width-200px、card--border-radius-8,导致响应式、主题切换、设计 token 替换全失效。
btn--primary(代表“主操作”,由设计令牌 --color-brand-primary 驱动)btn--loading(代表状态,可与 --primary 同时存在)btn--bg-blue-500(视觉值,主题换色时得全量替换)btn--primary--large--disabled(连缀式,无法单独覆盖或复用)真正卡住问题的,从来不是人记不记得规范,而是机器能不能当场拦住 .user-card .avatar 这种空格选择器、.disabled 这种孤立修饰符、或者 user-card__button-- 这种拼接漏参数的 JS 动态类名 —— 它们在审查元素里根本看不到效果,但会悄悄拖垮维护节奏。