在构建类似 Bootstrap 这样的 CSS 系统时,保持系统的简单性、稳定性、灵活性是相当重要的。这并非易事,尤其对于大型团队和项目来说,组件的数量可能会变得相当庞大。为了改善这种状况,你不妨考虑用前缀式类名取代链式类名。
在使用 链式类名 方案时,你可能会把一系列特定组件的 CSS 选择符写成这样:
- .success { ... }
- .btn.success { .. }
- .alert.success { ... }
我们在这里设置了一个全局基础类 .success
,它可能涵盖了成功按钮和成功提示框之间的所有共性。然后,在单个组件层面,我们又需要对它进行扩充或覆盖。但是,这种完全开放式的类名和链式风格令开发者面临一些困扰和潜在痛点:
- 这个基础类到底代表什么
- 哪些元素会在根层级受到影响(译注:啥意思?)
- 哪些元素可以把
.success
类链到自己身上 - 它是否可以被进一步扩展到更多的组件上
- 假如一个
.success
的实例要用白底绿字,而另一个要用绿底白字,怎么办?
而且这些问题还只是冰山一角。这种方案未必很差,但如果可扩展性、简单性和灵活性是你的***需求,这可能就不是***的办法。此时,前缀式类名方案可能更加适合你。
前缀式类名 将开发者引入一种更简单、更易维护的方向,从而构建一个可扩展的 CSS 系统。当我们抛弃常规的基础类的方式,并将每个组件的样式用前缀限制起来时,我们的代码会变成这样:
- .btn-success { ... }
- .alert-success { ... }
这样一来,基础类被设定在组件级别,而不是整个系统级别。换句话说,我们的基础类变成了 .btn
和 .alert
,而不是 .success
。所有组件之间都不会出现样式和行为上的相互干扰,因为我们把组件具备“成功状态”视为贯穿整个系统的一种概念。这就是说,每个组件在“成功”状态下的样式,只有在 概念 层面才是相通的;而对于如何 实现 这个样式,是被约束在每个独立的组件内部的。不用操心通用的样式还会在哪里使用,也不用顾虑不可意料的副作用,这种方式使得每个组件更加稳定和灵活。
构建组件是一项非常具有策略性并且注重细节的工作,在一个类似 Bootstrap 的系统中,组件需要天生具备独立性,以提高模块分离度和可定制性。我们通过这种方式来打造更好的代码和一个令人愉悦的项目。
我的体会
作者视角
我自己在 CMUI ***版中,基本上使用的是文章开头所说的“链式类名”风格。比如说,一个大号按钮的结构可能是这样的:
- <button type="button" class="cmBtn cmLarge">Large button</button>
而在 Bootstrap 中,类似的元素是这样的:
- <button type="button" class="btn btn-lg">Large button</button>
最开始我并没有觉得这两者有什么不同——前一个类名用于挂载框架预定义的按钮样式,后一个类名用于指定按钮的尺寸。把 Bootstrap 源码中所有的 .btn-lg
替换成 .cmBtn.cmLarge
,不就跟我的 CMUI 一样了嘛?我甚至觉得 Bootstrap 的类命名有点啰嗦,.btn
和 .btn-lg
中的 btn-
不是重复了吗?还是 CMUI 干净利落啊!
然而,看完这篇文章,我似乎体会到 Bootstrap 这种设计的好处。我的理解可能并不是原作者的出发点,但也不妨列举出来,仅供参考。
用户视角
这两种类名风格的差异并不在于源码是怎么写的,而是在于开发者(这里指使用 Bootstrap 的开发者)在看到类名时的反应。我的理解是,不同的命名,对开发者的暗示是不同的。
开发者们并不总是会按照组件文档的示例来编写组件的结构代码。比如说,某些时候他们手边没有文档(或不想找文档),又或者他们所期望的样式在文档中并没有列出。他们可能会抱着一种试试看的心态,尝试修改或组合手头的几个类名,以期产生某种新的样式效果。
如果类名是宽泛的(比如 CMUI 中的 .cmLarge
),就很容易被拿来尝试——比如开发者会给一个 ul.cmList
元素增加 .cmLarge
类并期望得到一个大号的列表,但实际上 CMUI 并没有提供这种组合!这破坏了开发者的预期,导致心理受挫,以致最终放弃这个组件库(夸张了点哈)。
但如果类名是被一个“组件级”前缀限定的(比如 Bootstrap 中的 .btn-lg
),那么它被开发者拿去组合到其它组件身上的可能性就相当低。即使某个异想天开的开发者试图把 .btn-lg
改成 .dropdown-lg
并应用到一个下拉菜单上,当他失败时,他应该也已经做好心理准备了罢。
结语
这样看来,Bootstrap 的做法确有它的好处,我的 CMUI 2.0 不妨也试试看。
你如何评论这两种类名风格呢?不妨留下你的观点吧!