stylelint-selector-bem-pattern是唯一能落地的bem校验手段,因其能在保存、提交、构建三环节自动报错拦截非法结构(如.card__title__sub、.modal .modal__content),且仅认准block__element--modifier三层语法锚点,缺一不可。

靠文档和口头约定无法统一 BEM,必须用工具链把规则“焊死”在保存、提交、构建三个环节——否则新人写错一个 .btn__icon,三天后就变成 .btn-icon、.button__icon、.BtnIcon 并存。
为什么 stylelint-selector-bem-pattern 是唯一能落地的校验手段
人工 Review 永远追不上手滑速度;VS Code 插件只能提示,不能阻断;只有 stylelint-selector-bem-pattern 能在保存时直接报错,且支持 CI 级别拦截。
- 它不校验“好不好看”,只认结构:必须有且仅有一个
__或--,且位置固定——.card__title--large合法,.card-title--large或.card__title__sub直接标红 - 配置里
componentName: '[a-z][a-zA-Z0-9]+'会拒绝UserCard、_header、card-1这类命名 - 它还能抓出更隐蔽的违规:
.modal .modal__content(结构选择器)、.card__title .card__text(后代嵌套)
如何让开发者不抵触、不绕过校验
强制不等于有效。如果校验太严或补全太弱,人会立刻找漏洞:比如在 JS 里拼字符串、用 !important 覆盖、或者干脆关掉插件。
- VS Code 必须配
BEM Helper插件,输入card回车自动展开card__title、card--hover等候选项,减少手敲错误 - React 项目中禁用裸字符串拼接,改用
clsx封装常量:const card = { base: 'card', title: 'card__title', body: 'card__body' },调用clsx(card.base, { [card.title]: isExpanded }) - SCSS 中禁用
&__item { &__text { } }写法——这会生成后代选择器,破坏 BEM 平级原则,必须写成&__item { } &__text { }
老项目怎么避免“统一标准=停工重写”
没人能说服 PM 推迟上线去改 200 个 .nav 类名。真正可行的是划清边界、守住新增、逐步收口。
- 所有新组件目录名即 Block 名:
/components/user-profile-card/→ CSS 文件必须叫user-profile-card.css,且只允许出现user-profile-card、user-profile-card__avatar、user-profile-card--compact - 高频冲突旧类(如全局
.table)不急于重命名,但加 wrapper 包一层:<div class="data-table">…</div>,后续扩展全走data-table__row、data-table--striped - 遗留 HTML 中的
class="card card--featured"必须确保 CSS 文件里同时存在.card和.card--featured规则——BEM 不允许修饰符脱离基础块单独生效
最易被忽略的一点:BEM 的 __ 和 -- 是语法锚点,不是视觉分隔符。漏一个下划线、多一个空格、用错连字符,工具链就失去识别能力,整个规范退化为“大家自觉”。它不解决层叠顺序,也不替代 CSS Modules,但它让每个类名变成可搜索、可推理、不可歧义的语义单元——这点一旦松动,协作成本就从分钟级涨到小时级。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











