BEM与SMACSS解决不同层级问题:BEM规范类名结构(block__element--modifier)和模块化文件组织,SMACSS划分样式职责(Base/Layout/Module/State/Theme)与维护分工。

没有“更适合”的规范,只有更匹配团队协作方式和项目演进阶段的规范。BEM 和 SMACSS 解决的问题不在同一层:BEM 管类名怎么写、文件怎么组织;SMACSS 管样式按什么职责分层、谁该维护哪部分。
BEM 的类名结构强制绑定上下文,适合组件强隔离场景
当你需要快速交付 UI 组件库、或团队成员频繁变动、或组件需跨项目复用时,BEM 的命名自带归属关系能显著降低理解成本。比如 .card__title--large 一眼可知它属于 card 模块、是 title 元素、处于 large 变体状态。
- 不允许
.menu__item__icon这类嵌套元素写法——必须拆成.menu__item-icon或独立.iconblock - 修饰符(
--disabled)本意是静态变体,不是运行时状态;混用button--is-loading会破坏语义,也难被postcss-bem类插件校验 - React/Vue 中动态拼接类名更安全:
className={`card__button ${disabled ? 'card__button--disabled' : ''}`不易漏空格或重复
SMACSS 的五层分类依赖人工约定,适合多组并行+架构分层明确的大型 Web App
当 Layout 层由前端架构组统一维护、Module 层由多个业务组各自负责、State 层需与全局状态管理对齐时,SMACSS 的 Base/Layout/Module/State/Theme 分层才真正起效。
-
base.css容易变成“全局垃圾场”:h1 { margin: 0 }和.btn { display: inline-block }混在一起,后期想抽离某条规则几乎不可能 - 状态类如
is-hidden是专为 JS 动态控制设计的,但容易误写成button-is-hidden(违反 State 层应独立原则) - 类名短但语义模糊:
active到底是菜单、Tab 还是表单项?得靠文档或上下文推断,协作成本隐性上升
BEM 按模块组织文件,SMACSS 按职责组织文件
文件定位效率差异直接影响日常开发节奏。
立即学习“前端免费学习笔记(深入)”;
- BEM 倾向一个模块一个目录:
button/下放button.css、button.js、button.test.js;改按钮样式只打开这一个地方 - SMACSS 把所有同类样式聚到一起:
modules/promo-card.css、modules/user-profile.css,好处是模块样式集中;坏处是两个相似卡片(article-card和product-card)细微差异就导致冗余 - 构建工具对两者都支持,但 BEM 更适配
postcss-bem做类名校验,SMACSS 主要靠人工 review 类名前缀是否符合类型约定
真正容易被忽略的是:BEM 的修饰符(--)和 SMACSS 的状态类(is-)语义不同、用途不同、生命周期不同。强行混合使用,既让构建工具失效,也让新成员无法从类名本身判断它是静态配置还是动态状态。


















