应使用语义化 Block 名(如 button 或 checkout-button)而非业务前缀(如 myapp-button),因硬加前缀损害复用性、破坏 BEM 稳定性、稀释修饰符语义,且现代构建工具可安全自动添加前缀。

硬加业务前缀会让 Block 失去复用能力
比如写 myapp-button,看似隔离了样式,实则把“按钮”这个通用 UI 单元绑定死了。后续想抽成独立 npm 包、或在 admin 系统里复用时,myapp-button 就成了语义污染——它不再表示“按钮”,而是“我的应用里的按钮”。真正可复用的 Block 名应是 button 或带领域语义的 checkout-button,后者本身已含上下文,无需额外前缀。
构建工具比手动拼接更安全可靠
现代构建链(如 PostCSS + postcss-prefix-selector)能自动给所有匹配 .button__icon 这类 BEM 类名的规则加统一前缀,同时排除第三方类(如 .ant-btn)。手动加 myapp- 不仅重复劳动,还容易漏掉 JS 层调用点:el.classList.contains("myapp-button__icon") 和 CSS 里写的 .button__icon 对不上,直接失效。
第三方库升级时会意外破坏你的命名契约
BEM 的稳定性依赖于类名结构可预测。一旦 Ant Design 新增了 .button--focus,而你写了 myapp-button--focus,两个选择器完全不匹配,焦点样式就丢了。更糟的是,有些库(如 Tailwind 的 arbitrary values)会动态生成类名,硬编码前缀会让这类场景彻底失控。
Modifier 和 Element 的语义会被业务词稀释
写 myapp-button--login 把业务场景(login)塞进 Modifier,违反了 BEM 对修饰符的核心要求:它必须是可枚举、可设计、跨场景一致的状态,比如 button--disabled。一旦 --login 变成 --register,就得改 CSS、JS、测试用例三处,且无法被 clsx 或 stylelint 自动校验。
立即学习“前端免费学习笔记(深入)”;
真正难处理的是 Block 边界的定义——它既不能太泛(如section),也不能太专(如 homepage-hero-banner-v2),得靠团队对业务域的共识来卡住,而不是靠字符串拼接来“假装隔离”。


















