再比如:关于组件命名规范:"如何给你的CSS class命名?聊聊BEM之外的选择

阿乐
阿乐 管理员 黑卡会员
发布于 2026-09-06 10:49 ·2 浏览 ·0 回复

好的,我已经理解您的要求,将直接开始撰写文章正文。


你是否曾经盯着一个写了半年多的项目,看着 `block__element--modifier` 这样冗长的类名,心里泛起一丝复杂的情绪?BEM 确实解决了命名混乱的问题,但它的冗长和视觉噪音也让人头疼。更关键的是,BEM 本质上是在用 HTML 结构去约束 CSS 作用域,这在组件化开发大行其道的今天,多少显得有些过时。

如果你对 BEM 的 `__` 和 `--` 感到疲惫,或者想寻找一种更贴合现代前端架构的命名思路,这篇文章想和你聊聊 BEM 之外的一些选择和思考。

BEM 到底解决了什么,又带来了什么

BEM 的核心价值并非美,而是可预测性。只要看到 `card__title--highlight`,你立刻知道这是一个 `card` 块内部的 `title` 元素,并且带有 `highlight` 修饰状态。这在无构建工具、纯 CSS 的年代,是维护大型项目的救命稻草。

但它的代价同样明显:HTML 会被塞满一堆长类名,视觉上很不友好;同时它鼓励你将组件的内部结构暴露在样式层。当组件内部结构重构时,CSS 类名也要跟着变,这增加了重构的成本。说白了,它强行用“平面”的命名规则模拟“树状”的组件关系,一旦嵌套深了,类名就会变得又长又难读。

OOCSS 与 SMACSS:结构性思维的余晖

在 BEM 广泛流行之前或同期,还有两位老前辈常被提及。OOCSS(面向对象 CSS)的核心是“结构与皮肤分离”和“容器与内容分离”。它的思路是像写 JavaScript 一样,把重复的“视觉模式”抽成独立类。比如 `.btn` 负责布局尺寸,`.btn--blue` 负责皮肤颜色,之后在 HTML 里直接组合使用。

SMACSS 则将样式分为 Base、Layout、Module、State、Theme 五类。它不执着于某个类名长什么样,而是逼迫你在写代码前先思考:“这到底是布局、模块还是状态?”

坦白说,这两个方案在今天依然有指导意义,但它们对团队纪律要求极高。如果没有良好的文档和审查机制,很容易退化成一场“自由发挥”的命名混乱。它们更适合用来启发思考,而不是直接作为团队的唯一规范。

现代 CSS 方案下的结构性替代品

如果你维护的是一个使用 Vue、React 的现代项目,其实可以跳出“纯命名”的框框,把结构问题交给框架解决,让 CSS 只管“皮肤”。

- CSS Modules:这是带有“局部作用域”的 CSS 文件。你不再需要手工维护 `block__element`,只要写 `.title` 或 `.highlight`,构建工具会自动加上哈希后缀,保证全局唯一。类名的语义从“在哪里”变成了“是什么”,简洁了很多。缺点是调试时需要开启 sourcemap,否则看到的是一堆随机字符。

- CSS-in-JS(如 styled-components):它更进一步,连单独的 CSS 文件都省了。样式与组件绑定,命名彻底无关紧要,因为最终生成的类名是工具生成的。这带来了极致的“内聚性”——组件删掉时样式一并消失,不会有遗留的 CSS 死代码。它的代价是性能损耗(虽然微乎其微)以及偏离了 Web 平台“内容-表现分离”的原教旨。

- Utility-First(如 Tailwind CSS):如果说 CSS Modules 和 CSS-in-JS 是“消灭命名”,那 Tailwind 就是“用原子化的预置类去组合”。你几乎不写自己的类名,只在 HTML 里堆 `flex p-4 bg-red-500`。这本质上是一个设计约束系统,促使你在设计体系内工作,而不是随手在样式表里写 `margin: 13px` 这种魔法值。它的争议在于 HTML 可读性被严重破坏,但配合组件化框架(只用在模板里),体验反而出奇地好。

如果你还是想用 BEM,试试它的轻量变体

如果你的项目无法引入构建工具,或者需要给老项目制定规范,也不想完全抛弃 BEM 的可预测性,可以考虑以下两个改良方向:

1. BEM + Utility 组合:只对真正负责布局和皮肤复用的部分用原子类,对组件结构用短 BEM。比如 `<div class="card p-4"> <h2 class="card-title mb-2">`。这里用简短的 `card-title` 替代 `card__title`,因为子元素的边界已经由组件的模板(HTML 结构)清晰界定,没有必要用 `__` 重复宣告父子关系。

2. 低特定性的块命名:只定义“块”名(即组件名),元素直接放在块名之下,用后代选择器(配合 `>` 保持一层)。比如 `.card > h2`。这虽然违背了 BEM 不要用标签选择器的禁忌,但在局部作用域下(比如配合 `scoped`)其实是可控的。

最后的一点建议

在我看来,CSS 命名规范从来不是技术问题,而是合作共识问题。你真正需要的不是一个美丽的命名法,而是一套能让团队成员之间不互相踩脚趾的协作协议。BEM 是一副好牌,但它不适合每个人;Tailwind 像是一把快刀,但也可能割伤自己。

不妨先问问你的团队:我们是需要更强的结构可读性,还是更快的开发速度?能否接受构建层的复杂性?如果答案是“要结构”,挑一个正式规范并严格执行五年,都比朝令夕改好得多。

命名之争,本质是工程取舍之争。别试图找“全局最优解”,找到一个限制最少、最能让团队舒服前进的“局部最优解”,就很好。

全部回复 0

还没有回复,来抢沙发~