缩写不是bem的问题,而是语义丢失的开始——user-card__avt--lg比user-card__avatar--large更危险,因缩写切断命名与dom、js、沟通的映射链,导致调试困难、补全失效、搜索歧义、新人成本高;仅btn/txt/img/cnt等极少数全项目统一缩写可接受,且须用eslint/stylelint校验;modifier必须表达意图而非值,尺寸应交由css自定义属性控制。

缩写不是BEM的问题,是语义丢失的开始——只要类名让人得停顿半秒去猜,它就已经失败了。
为什么user-card__avt--lg比user-card__avatar--large更危险
缩写本身不违法,但会切断命名与 DOM 结构、JS 逻辑、团队沟通之间的映射链。调试时看到 avt,没人能立刻确认它是 avatar 还是 activity;查 uc-avt 更糟,连属于哪个 Block 都得翻 HTML。
- IDE 自动补全失效:
user-card__av不会提示出avatar,但user-card__a可能匹配到action、avatar、alert - 搜索替换不可靠:全局搜
avt可能误中notification__avt-badge和activity__avt-icon,而avatar基本无歧义 - 新人上手成本翻倍:文档里写“avt = avatar”,等于把语义责任推给注释,而非代码本身
card__ttl这类缩写在什么场景下勉强可接受
仅当满足全部三个条件:缩写已被团队长期统一使用、对应单词在项目中出现频次极高(如 title 在每个 Block 里都存在)、且所有成员口头/文档中均用同一缩写指代——否则一律拒绝。
- 真实可行的缩写只有极少数:
btn(button)、txt(text)、img(image)、cnt(content)——且必须全项目统一,禁止btn和button混用 -
usr不行(user 无歧义,长度可接受),ctn不行(container 太泛,card__ctn看不出是 content 还是 container) - 一旦引入缩写,就必须进 ESLint 规则或 Stylelint 插件校验,例如用
stylelint-selector-bem-pattern拦截__avt类匹配
修饰符里用缩写比元素名里更致命
card--sm 看似省事,但它抹掉了状态意图:sm 是 small?summary?smart?而 card--compact 或 card--condensed 直接表达设计目的。
- Modifier 必须回答“这个状态意味着什么”,而不是“这个值是多少”——
--lg是尺寸值,--featured是业务意图 - 多个 Modifier 共存时缩写灾难加倍:
btn--p-sm--d-true--v-outlinevsbtn--primary--disabled--outline,后者 JS 切换类、CSS 调试、Code Review 全部降噪 - 如果真要控制尺寸变量,交给 CSS 自定义属性:
<button class="btn" style="--btn-size: 14px"></button>,类名保持语义干净
最常被忽略的一点:缩写一旦进 HTML,就等于把语义决策锁死在模板层。后面想改 avt 为 avatar,得同步改 HTML、CSS、JS、测试、文档——而一开始写对,只多敲 3 个字母。











