bem和smacss是解决不同问题的两类工具:bem规范类名书写与模块化文件组织,smacss聚焦样式职责分层与维护分工;二者在类名结构、文件组织、性能影响、框架协作及适用场景上存在系统性差异。

BEM 和 SMACSS 不是“谁更好”,而是解决不同问题的两类工具:BEM 管类名怎么写、文件怎么组织;SMACSS 管样式按什么职责分层、谁该维护哪部分。
类名结构差异:BEM 强制归属,SMACSS 允许组合
BEM 的类名自带上下文约束:card__title--large 必须属于 card 这个 block,card__title 不能单独存在,也不能再嵌套元素(card__title__icon 是反模式)。SMACSS 则不强制归属,promo-card 和 is-hidden 是两类独立职责的类,可以自由组合:promo-card is-hidden 合法,promo-card-title 也合法——只要团队约定清楚前缀含义。
常见错误现象:
- BEM 中写
header__nav__item,实际应拆成navblock 或用nav__item - SMACSS 中把状态类硬塞进模块名,比如
button-is-loading,违背了state层应独立的原则
文件组织逻辑:BEM 按模块切,SMACSS 按职责切
BEM 项目里,一个 button/ 目录通常包含 button.css、button.js、button.test.js,所有与 button 相关的东西都在一起。SMACSS 则把所有布局类塞进 layout.css,所有基础重置塞进 base.css,所有模块样式按功能分在 modules/card.css、modules/form.css 等。
性能 / 兼容性影响:
- BEM 文件定位快,但跨模块复用困难——两个相似 card 组件各自维护,细微差异就导致样式冗余
- SMACSS 的
base.css容易变成“全局垃圾场”,h1 { margin: 0 }和.btn { display: inline-block }混在一起,后期抽离某类规则成本极高
与现代框架协作时的收敛难度
在 React 或 Vue 组件中,BEM 类名天然映射组件结构:Card 组件输出 card、card__header、card--fluid,JSX 和 CSS 耦合清晰可控。SMACSS 的状态类常被动态拼接进 className,容易出错:className={`btn ${loading ? 'is-loading' : ''}` 可能漏空格、重复添加、或忘记移除旧状态。
使用场景差异:
- 用 BEM:你正在封装 UI 组件库,需要强隔离、低协作成本、快速交付
- 用 SMACSS:你有多个前端小组并行开发,Layout 层由架构组统一维护,Module 层由业务组各自负责,且状态变更需与 JS 状态管理对齐
真正容易被忽略的是:BEM 的修饰符(--disabled)本意是静态变体,不是运行时状态;SMACSS 的 is- 类才是专为动态状态设计的。混用这两者,比如在 BEM 中写 button--is-loading,既破坏命名语义,又让构建工具难校验、团队难对齐。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











