A Better Front-End Guideline

SMACS - CSS Guideline

1. Five Types Of Categories (五个分类模块)

  1. Base (重置样式)
  2. Layout (布局样式)
  3. Module (模块样式)
  4. State (状态样式)
  5. Theme (主题样式)

这里需要提及的是 Layout 这部分文章中更多地偏向于定位和共用元素,没有具体到一个模块 Module ,所以鉴于不同网站的需求,我会将分类扩展成 6 个,即:

  1. Base (重置样式)
  2. Layout (布局样式)
  3. Module (模块样式)
  4. Component (组件样式)
  5. State (状态样式)
  6. Theme (主题样式)

定义模块和组件的区分在于,模块一般是由内容和组件构成的。模块一般与内容有关,组件一般是独立存在的。

( 如果用人体来做比喻的话:Layout 更多地指骨架,而 Module 更多指一个功能单位,例如手臂或者是腿部,Component 就是构成 Module 的独立单位,可以运用在不同的 Module 之间,例如细胞皮肤等等。 )

2. Base Rules (基础样式书写规范)

A Base rule is applied to an element using an element selector, a descendent selector, or a child selector, along with any pseudoclasses.It doesn’t include any class or ID selectors. It is defining the default styling for how that element should look in all occurrences on the page.

重置样式更多地是使用元素选择器或者子选择器和后代选择器去定义,含有类或者 id 选择器的都不算是基础样式,例如:

body, form {
    margin: 0;
    padding: 0;
}
a {
    color: #039;
}
a:hover {
    color: #03F;
}

当然我们除了基础样式外还有一些基础的重置样式,方便我们快速定位或者重用的,例如:

.pr {position: relative;}
.pa {position: absolute;}
.zomm {zoom: 1;}
.hidden {overflow: hidden;}
.none {display: none;}
.clearfix:before,.clearfix:after {content: ".";display: "block";height: "0";visibility: hidden;}
.clearfix:after {clear: both}
.clearfix {zoom: 1}

3. Layout Rules (布局样式书写规范)

布局样式着重于增加模块和组件的重用性,例如我们有以下的一个布局:

根据以上这个要求,我们可以使用以下的代码去实现,并且可以完美实现这一布局:

<div>
    <h2>Features</h2>
    <ul>
        <li><a href="…">…</a></li>
        <li><a href="…">…</a></li>
    …
    </ul>
</div>
div#featured ul {
    margin: 0;
    padding: 0;
    list-style-type: none;
}
div#featured li {
    float: left;
    height: 100px;
    margin-left: 10px;
}

但是我们这样子就把这一模块写固定了,这种常用的布局可以运用在很多地方,无论是图片的排版,产品排版或是文章的排版都可以使用,所以我们可以用下面的方式更好地解决重用性的问题:

.l-grid {
    margin: 0;
    padding: 0;
    list-style-type: none;
}
.l-grid > li {
    display: inline-block;
    margin: 0 0 10px 10px;
    /* IE7 hack to mimic inline-block on block
    elements */
    *display: inline;
    *zoom: 1;
}

这样子的话我们就可以很方便的把我们的这个模块分别放置到不同的运用场景,只需要我们把模块下的组件(例如图片模块,产品模块或文章模块)就可以方便地嵌套了。

4. Module Rules (模块样式书写规范)

A Module is a more discrete component of the page. It is your navigation bars and your carousels and your dialogs and your widgets and so on.

文章中关于模块样式的定义其实已经包含了模块样式,而我在这里将其分开是更方便于查找和共用。还是那样一句话,根据项目的需求进行分解。

关于模块样式,有如下几点需求:

a.避免使用 id 选择器,尽量使用 类 选择器

b.内部避免元素选择器(如果组件内部的元素可预测的话即可)

例如以下代码:

<div class="fld">
    <span>Folder Name</span>
</div>
/* The Folder Module */
.fld > span {
    padding-left: 20px;
    background: url(icon.png);
}
<div class="fld">
    <span class="fld-name">Folder Name</span>
    <span class="fld-items">(32 items)</span>
</div>

c.多用子类去定义组件,使其更加扩展化

假设我们有一个.pod的组件,在不同的区块有不同的长度,相对于以下的代码:

.pod {
    width: 100%;
}
.pod input[type=text] {
    width: 50%;
}
#sidebar .pod input[type=text] {
    width: 100%;
}
.pod-callout {
    width: 200px;
}
#sidebar .pod-callout input[type=text],
.pod-callout input[type=text] {
    width: 180px;
}

我们可以扩展为:

.pod {
    width: 100%;
}
.pod input[type=text] {
    width: 50%;
}
.pod-constrained input[type=text] {
    width: 100%;
}
.pod-callout {
    width: 200px;
}
.pod-callout input[type=text] {
    width: 180px;
}

从而提高在不同页面中的重用率。

4.State Rules (状态样式书写规则)

A state is something that augments and overrides all other styles.For example, an accordion section may be in a collapsed or expanded state. A message may be in a success or error state.

状态样式一般作用于模块和组件,例如下面的代码:

<div id="header" class="is-collapsed">
    <form>
        <div class="msg is-error">
            There is an error!
        </div>
        <label for="searchbox" class="is-hidden">Search</label>
        <input type="search" id="searchbox">
    </form>
</div>

headerform 都可以当成一个模块,而 msg , labelinput 则是一个组件。

a.如何区别 sub-module 和 state style?

通过添加子类和子模块和状态样式都可以修改一个组件的样式,那么如何区别他们呢?我们可以通过以下的方法去区别:

  • 状态样式可以作用于模块和组件;
  • 状态样式一般会结合 Javascript 进行使用。

b.可以使用 !important

虽然我们不推崇使用过多的 !important,但是在修改状态样式的时候,我们会去 override 组件或者是模块的样式,所以在必需的时候,!important还是可以使用在状态样式的。

c.命名时注意添加对应的组件名称

状态样式(如果是独有的话)对应的哪一个组件或者模块,在命名的时候还是很有必要加上,方便区分不同的状态样式:

.tab {
    background-color: purple;
    color: white;
}
.is-tab-active {
    background-color: white;
    color: black;
}

5.Theme Rules (主题样式书写规范)

主题样式虽然对于一般网站来说不是很经常会用到的,但对于开发者来说,把用过的东西换个脸就可以给下一家客户了!所以在开始的时候定义好主题样式对于以后的扩展来说是十分方便的。

来看主题样式的一个基本例子:

/* in module-name.css */
.mod {
    border: 1px solid;
}
/* in theme.css */
.mod {
    border-color: blue;
}

这样子的话我们就可以给 .mod 这个类添加不同的元素,或者着更加优化的做法是在可以主题化的元素前面加上 theme-的前缀,可以运用到更多的场景,就如SCSS一般,用上面的例子来修改的话可以写做:

/* in theme.css */
.theme-border {
    border-color: purple;
}
.theme-background {
    background: linear-gradient( ... );
}