分类
CSS

模块化CSS

如今,CSS理论几乎和CSS或JavaScript框架一样多。但CSS或JavaScript框架的用法较为繁琐,而且必须成套使用,而CSS理论更多的是阐释HTML 和CSS之间的关系,而不是预编译的代码库,因此使用起来更为灵活。

前端架构师的你好像每天都会听说一个新的方法,例如使用新的命名空间、扩充数据属性,甚至是在JavaScript里定义CSS。这些理论都有它的亮点,能够在如HTML和CSS的关系方面给你一些新的启发。这些理论都有它的亮点,能够在如HTML 和CSS 的关系方面给你一些新的启发。当然,没有哪个方法论是完美的,你可能会发现,一个项目与某一个方法契合得最好,但是另一个项目却更适合用另一个方法。所以,你完全可以创造自己的方法论,或者将一个现有的理论根据自己的需求进行改造。因此,如果你犹豫不决,不知道如何选择方法论,最好是看一些比较杰出的方法论,根据你手头的项目来分析其中哪些可用,哪些不可用。

一、OOCSS方法

下面的代码片段展示了如何使用OOCSS(Object-Oriented CSS,面向对象的CSS)方法创建一个HTML切换。

<div class="toggle simple">
  <div class="toggle-control open">
     <h1 class="toggle-title">Title 1</h1>
  </div>
  <div class="toggle-details open"> ... </div>
  ...
</div>

OOCSS有两个主要的原则:分离结构和外观,以及分离容器和内容。

分离结构和外观,意味着将视觉特性定义为可复用的单元。前面那段简单的切换就是一个简短的可复用性强的例子,可以套用很多不同的外观样式。例如,当前的“simple”皮肤使用直角,而“complex”皮肤可能使用圆角,还加了阴影。

分离容器和内容,指的是不再将元素位置作为样式的限定词。和在容器内标记的CSS 类名不同,我们现在使用的是可复用的CSS 类名,如toggle-title, 它应用于相应的文本处理上,而不管这个文本的元素是什么。这种方式下,如果没有应用别的CSS 类名,你可以让H1标签以默认的样式呈现。

当你想提供一套组件让开发人员组合起来创建用户界面时,这种方法非常有用。Bootstrap就是一个特别好的例子,它是一个自带各种皮肤的小组件系统。Bootstrap 的目标是创建一个完整的系统,而且这个系统能够创建开发者可能需要的任何用户界面。

二、SMACSS方法

同样以切换组件为例,按照SMACSS(Scalable and Modular Architecture for CSS,模块化架构的可扩展CSS)方法,写出来的代码如下:

<div class="toggle toggle-simple">
  <div class="toggle-control is-active">
    <h2 class="toggle-title">Title 1</h2>
  </div>
  <div class="toggle-details is-active">
    ...
  </div>
  ...
</dl>

尽管SMACSS和OOCSS 有许多相似之处,但SMACSS 的不同点是把样式系统划分为五个具体类别。

基础

如果不添加CSS 类名,标记会以什么外观呈现。

布局

把页面分成一些区域。

模块

设计中的模块化、可复用的单元。

状态

描述在特定的状态或情况下,模块或布局的显示方式。

主题

一个可选的视觉外观层,可以让你更换不同主题。

在前面的例子中,我们看到了模块样式(toggle、toggle-title、toggle-details)、子模块(toggle-simple)和状态(is-active)的组合。对于如何创建功能的小模块,OOCSS和SMACSS有许多相似之处。它们都把样式作用域限定到根节点的CSS类名上,然后通过皮肤(OOCSS)或者子模块(SMACSS)进行修改。除了SMACSS 把代码划分类别之外,两者之间最显著的差异是使用皮肤而不是子模块,以及带is前缀的状态类名。

三、BEM 方法

这里同样以切换组件为例,使用BEM(Block Element Modifier,块元素修饰符)语法写出组件代码:

<div class="toggle toggle--simple">
  <div class="toggle__control toggle__control--active">
    <h2 class="toggle__title">Title 1</h2>
  </div>
  <div class="toggle__details toggle__details--active">
    ...
  </div>
  ...
</dl>

BEM 是我们要介绍的第三个方法,是SMACSS的另一个方面。BEM只是一个CSS类名命名规则。它不涉及如何书写你的CSS的结构,而只是建议每个元素都添加带有如下内容的CSS类名。

块名

所属组件的名称。

元素

元素在块里面的名称。

修饰符

任何与块或元素相关联的修饰符。

BEM 使用非常简洁的约定来创建CSS 类名,而这些字符串可能会相当长。元素名加在双下划线后(例如toggle__details),修饰符加在双横杠后(如toggle__details–active)。这里的details是元素,active是修饰符,这个约定使得CSS类名非常清晰。使用双横杠是为了避免块名被混淆为修饰符。

这种方法在OOCSS或SMACSS里使用的好处是,每一个CSS类名都详细地描述了它实现了什么。代码中没有open或者is-active这样只在特定背景下才能理解的CSS类名。如果单独看openis-active这两个名字,我们并不知道它们的含义是什么。虽然BEM方法看起来很累赘、很冗余 ,但是当看到一个toggle__details--active的CSS类名,我们就知道它是表示:这个元素的名称是details,位置在toggle组件里,状态为激活。

当然,最重要的还是要找到一个适合的解决方案。不要因为一套规范很流行或者别的团队正在使用就选择它。这三种方法都提供了类似的工具,并且以相近的方式在系统中使用。

节选自《Frontend Architecture for Design Systems》