# 规则分类

每个项目都需要一些组织架构。把所有样式写在单个CSS文件中会使得定位搜索某个样式变得十分困难,也让其他人的工作变得困难。当然,你可能已经有了一些组织架构,并且在阅读完这些文章之后,发现你的流程架构比我的更好。不过,也有可能你会找到一个提升工作流的新方法。

你知道何时使用ID选择器,何时使用Class选择器吗?你知道不同元素应该如何应用样式吗?你能轻松对网站和样式进行组织架构吗?

如果你不知道,看下去。

SMACSS的核心是分类。对CSS规则进行分类,我们会得到关于CSS架构的各个模式,而围绕这些模式,我们就能有更好的开发体验。

我将CSS规则分为5类:

  1. Base(基础)
  2. Layout(布局)
  3. Module(模块)
  4. State(状态)
  5. Theme(主题)

你可能会发现自己的样式混合了上述几种类别,这让你的样式变得更加复杂。不过,如果你意识到你写的样式属于哪一类,那将大大降低样式的复杂度。

这里的每个类别都有一些适用的准则。这些分类的准则能够让我们在开发过程当中问自己:我该如何编写这些样式,为什么我要这样编写代码?

其实我们对事物进行分类的主要目的是将那些重复出现的模式分类。这种可复用使得我们可以编写更少代码,维护更加简单,用户体验更加一致。这是个多赢的选择。当然,分类之外的东西未必无用,你得好好安排它们。

基础(Base)规则里放置默认样式。这些默认样式基本上都是元素选择器,不过也可以包含属性选择器,伪类选择器,孩子选择器,兄弟选择器。本质上来说,一个基础样式定义了元素在页面的任何位置应该是怎么样的

// 基础规则的例子
html, body, form { margin: 0; padding: 0; }
input[type=text] { border: 1px solid #999; }
a { color: #039; }
a:hover { color: #03C; }

布局(Layout)规则将页面拆分成几个部分,每个部分都可能有一到多个模块。

模块(Modules) 是我们的设计当中可重用,可模块化的部分。插图,侧边栏,产品列表等等都属于模块。

状态(State)规则 定义了我们的模块或者布局在特殊的状态下应该呈现怎样的效果。是hidden呢?还是expanded呢?是active还是inactive?
例如,它可能定义模块、布局在不同显示屏上应该如何显示。也可能定义一个模块在不同页面(例如主页和内页)中可能呈现怎么样的效果。

主题(Theme)规则 和状态规则类似,定义模块或者布局的外观。大部分网站并不需要这一层,但如果我们能注意到这一层,那就更好了。

# 命名规则

将规则分成五类之后,还需要命名规范。命名规范能够使得我们立刻了解到某个样式属于哪一类,以及它在整个页面中起到的作用。在一个大型项目中,我们可能会将一个样式分割成几个文件,这个时候命名约定能够使得我们更容易知道这个样式属于哪个文件。

我倾向于使用前缀来区分布局(Layout),状态(State)和模块(Module)规则。对于布局规则,我使用l-作为前缀,layout-也行。当然,像grid-也同样能够将布局样式从其他样式中提取出来。对于状态规则,我喜欢使用is-,例如,is-hiddenis-collapsed。这都能大大提高了样式的可读性。

模块是项目的主体,因此我们没有必要用类似.module这样的前缀。模块只需要使用模块自身的名称即可。

/* 示例 */
/* Example Module */
.example { }

/* Callout Module */
.callout { }

/* Callout Module with State */
.callout.is-collapsed { }

/* Form field module */
.field { }

/* Inline layout  */
.l-inline { }

而模块当中的相关元素则可以以基本名称为前缀。就比如这个网站,代码示例的模块,我使用了.exm而模块中的标题则使用了.exm-caption。当我看到.exm-caption时,我能够立马知道这个元素属于哪个模块以及我能够在哪里找到这个样式。

有时,我们可能会写一个模块的变体,这时我们也应该使用基础模块的名称作为前缀。至于子模块我们将会在_模块规则_章节做更详细的描述。

以上命名规范我将会在接下来的文章中一直使用。和我以前说的一样,不要拘泥于这些规则。你只要有个规范,记录下来,然后坚持下去就可以了。