CSS 命名规范:BEM、OOCSS 与 CSS Modules 怎么选

CLARA轻量论坛系统
CLARA轻量论坛系统 星耀SVIP管理员 黑卡会员
发布于 2026-09-17 19:18 ·2 浏览 ·0 回复

结论:没有银弹——**没有构建链路或多层传统项目选 BEM,需要跨组件复用的样式抽象叠 OOCSS,用了 React/Vue 这类组件框架且能改构建配置就直接上 CSS Modules**,而且三者可以叠加使用,不是单选题。

先分清它们解决的不是同一个问题

BEM 解决的「命名冲突与可读性」,OOCSS 解决的是「样式复用与抽象」,CSS Modules 解决的是「作用域隔离」——三个问题维度不同,所以能共存。

BEM 是一套命名约定,靠人自觉执行,零成本零依赖;OOCSS 是一套组织思想,本身不规定写法;CSS Modules 是构建期方案,靠工具把类名编译成 hash,从根上消灭冲突。判断顺序建议是:**你的项目有没有构建工具?有 → 优先 CSS Modules;没有 → BEM 打底。团队里是否存在大量重复的按钮/卡片样式?有 → 在设计层引入 OOCSS 思路。**

BEM:传统项目性价比最高的方案

结论:只要项目是「HTML 模板 + 手写 CSS」、没有组件编译环节,BEM 就是最省事的规范,因为它不依赖任何工具链。

BEM 即 Block(块)、Element(元素)、Modifier(修饰符),写法是 `.block__element--modifier`。一个完整的例子:

<div class="card card--featured">
  <h3 class="card__title">标题</h3>
  <button class="card__btn card__btn--disabled">操作</button>
</div>

核心纪律有两条:一是选择器保持扁平,嵌套不超过一层,禁止 `.card .card__title .icon` 这种长链,扁平选择器权重一致,覆盖样式时不用靠 `!important` 打架;二是元素类名不带块前缀以外的上下文,`.card__title` 只属于 card,不能挪到别处复用,需要复用就提升为新的块。

缺点也很直接:名字太长,手写费劲,深层结构会出现 `user-profile__setting-item__icon` 这种三段式灾难。经验做法是元素名不超过两级,超了就拆块。

OOCSS:把「结构」和「皮肤」拆开

结论:OOCSS 的两条原则——结构与皮肤分离、容器与内容分离——至今仍然有效,它本质上是后来原子化 CSS 的思想源头。

举例,按钮的圆角、内边距、字号属于结构,放进 `.btn`;颜色、背景、边框属于皮肤,放进 `.btn--primary`:

.btn { display: inline-block; padding: 8px 16px; border-radius: 4px; }
.btn--primary { background: #2b6cb0; color: #fff; }

好处是新增一个主题只要加皮肤类,不用复制整个按钮样式。但要注意它的副作用:皮肤类一多就会命名通胀,`.btn--primary--large--round--shadow` 这种串烧必须禁止。正确做法是把尺寸、形状等维度也各自拆成独立类,让 HTML 里多个类组合出结果,而不是靠一个长名字。

实践建议:OOCSS 只用在真正高频复用的基础组件(按钮、标签、表单控件、栅格)上,业务区块老实写 BEM,否则抽象成本会超过收益。

CSS Modules:让工具替你保证不冲突

结论:在 React/Vue 等组件化项目里,如果类名冲突已经靠人管不住了,CSS Modules 是投入产出比最高的解法,代价是学习 `composes` 和 `:global` 两个语法。

它的原理不复杂:`.title { }` 编译后会变成类似 `.title_x7d2k` 的哈希类名,作用域天然只在当前组件内。复用靠显式声明:

.title {
  composes: heading from "./base.css";
  font-size: 18px;
}

三个必知注意点:一是需要写全局样式时用 `:global(.xxx)` 包裹,否则会被一起哈希化;二是第三方库的类名(如某些 UI 框架)不要试图用 Modules 覆盖,老老实实写在全局样式文件里;三是动态类名拼接时用 `classnames` 之类的工具,别自己拼字符串,否则容易出现 `undefined` 混进 class。

另外一个常见误区:CSS Modules 不解决复用,它只解决隔离。如果你在组件里到处粘贴同样的按钮样式,Modules 帮不了你,还是得回到 OOCSS 的抽象思路上来。

落地建议:分层,而不是三选一

结论:成熟的样式架构通常是三层叠加——基础层放设计变量与 reset,布局层用工具类或 OOCSS,组件层用 CSS Modules 或 BEM。

具体点说:设计变量(颜色、间距、字号)抽成 CSS 自定义属性;布局用少量工具类(`.flex`、`.gap-8`)解决;业务组件按项目条件二选一。迁移时不要一次性全量重写,新写的按新规范走,老代码在改动到它的时候顺手改,避免制造一个大而全的重构分支。

最后提醒一句:任何命名规范的价值都低于「团队一致执行」。三个人用 BEM、两个人用 BEM 混 OOCSS、一个人写 Modules,比全员统一用最土的 BEM 要糟得多。先把规范写进代码评审清单,再谈选型。

本文转载自 Clara轻量论坛系统,原文地址:https://www.leleweb.cn/thread-450.html
转载请注明出处,版权归原作者所有。

全部回复 0

还没有回复,来抢沙发~