瞎扯扯OOCSS,ACSS,BEM,SMACSS

最近在看一些 CSS 的东西,想要提高一下自己在这方面的姿势水平。很久之前就了解到 BEM 了,当时还是在 ifanr 工作的网红莎莎大神和我说了这个。突然想到自己似乎也应该深入去了解一下这些东西。于是就看了一些资料,整理一下,且做个记录。

我这几年写 CSS ,核心的想法就是组件化模块化,这样就更好控制也减少改一个小东西整个页面爆炸了的可能性。所以如何去组织 CSS 也是蛮重要的一部分。

Object Oriented CSS (OOCSS)

面向对象的 CSS,字面意思就大概是这样把,反正一看到 OO 脑子里第一个反应就是 Java 的那种风格,可能是我安卓写多了……

OOCSS 的想法首先要明白 CSS 的 “Object” 是个毛线玩意。我粗鄙的理解下,应该一般指一个视觉上的图案、控件等,就是一个 Object ,大部分情况下,这种 Object 肯定是可以复用的。

常见的比如 Button ,按钮。

Tag : a,button  
calss: btn  

视觉上就可能是一个图形按钮等等,这里不展开说了,有兴趣可以去看 https://github.com/stubbornella/oocss/wiki

OOCSS 有个特点就是结构和皮肤是分开的,比如说一个渐变按钮,那么 .btn 的 class 是不会包含渐变相关的属性的,而是需要单独抽取出一个渐变的 class,然后让 .btn 去扩展从而得到一个渐变的按钮。

就像官方说的那样,一个 Object 包含了四个部分:

  1. HTML ,会有一个到多个的 DOM 节点
  2. CSS , 用来表示上述节点的样式, 这些样式都会以最外面的包裹层 Node 的 class Name 开始
  3. 背景图片、或者其他的一些用来展示的资源组成的组件
  4. Javascript 的事件,行为等。

另一个特点在于,OOCSS 认为 container 和 content 是需要隔离开的。也就是说,尽量不要去使用依赖于节点结构位置的样式定义。比如这样的就是不允许的:

.video-container .title{
  ...
}

OOCSS 中会建议你直接这样去写:

.title{
  ...
}

也就是直接去写这个元素。

另外 OOCSS 也定义了一整套的 Module Grid 等等,有兴趣可以去看 https://github.com/stubbornella/oocss/wiki

Atomic CSS

这个东西我是最近才看到的,官网上它也自称是为了组件化的 CSS 而设计的产物。顾名思义,这货的原则就是原子化的提供 class ,让你用起来非常顺手就像 inline 的 style 一样。

有一个思想叫做 Atomic Design ,简而言之就是一切都是原子组件构造而成。比较有趣的是,这个思想引入了一些科学名词,具体请看后面的介绍。

那么什么是原子(Atom)呢?

  • 每一个 HTML 元素就是一个原子。比如一个 input

然后用原子组成分子(molecules)

  • 就是一堆原子组件得到的东西,比如说一个输入框,前面有个 label,中间有个input,最后还有个提交 button

接着合成生物体(Organisms)

  • 所谓的生物体(不知道翻译的对不对,反正大概就是有机物之类的东西)就是一堆分子组合而成的,最简单的例子就是网站的一个 header 里面包含了搜索框、导航栏也许还有用户中心什么的。

之后一层就是比较正经的名字了,叫模版 (Templates):

  • 这个的话大家都应该熟悉了,在 ACSS 里面模版也就是把各种东西组合起来之后的布局等,基本上整个站点的结构都已经成型了

最后一层就是页面(Pages)

  • 这个就更简单了,就是加上图片等等其他的乱七八糟的东西,得到了最终的页面

Atomic CSS 有一点特别有趣的的是,基本上抛弃了所有的原来 CSS 的做法。它会针对每个选择器定义一个可以复用的 class 。比如:

.Bgc-fff{
   background-color:#fff;
}
<div class="Bgc-fff"></div>  

当然,引入一些预处理的手段后,你写出来的代码可能就是这样的了:

<div class="Bgc(#fff)">  
</div>

看上去是不是很扯,但是相信你已经 get 到 ACSS 的点了。其实就是 Style with class,就好像你所有的样式都是 inline 了一样一目了然。好处就是不用在管理各种页面各自的样式文件了,你准备好一个原子库,直接写 html 就能把样式写出来。问题也很明显,如果要做响应式就会比较麻烦,因为你的样式都是原子性的写在 html 中,那么可能比较简单的方法就只能是根据平台下发不同的 html 来解决这一个问题了。

总之还是蛮有趣的一个方案。 

Block,Element,Modifier(BEM)

BEM 相对来说就比较有名了,简单的说,就是通过遵循一套严格但合理的命名规范使得你的 class 保持一个较好的可读性和维护性。
好处也很明显,方便合作开发,别人容易读得懂你的代码,你也容易维护好你的样式。这个就直接上例子了:

.block{}

.block__element{}

.block--modifier{}

格式大约就是如上所属那样,当然,有一点需要注意,多层 DOM 节点的情况下正确的写法应该是这样的:

<div class="block">  
    <div class="block__e1">
       <button class="block__e2"></button>
    </div>
</div>  

这里的 button 不能写出 block__e1__e2 这样就太丑了。

Stackoverflow 上有个特别好的解释对于 BEM 的说法点这里查看

简单说,就是 html 是一个 DOM树,那么你在写样式的的时候就写成一个 BEM树一一对应就可以了。看例子:

html:

<ul>  
  <li>
     <a>
       <span></span>
     </a>
  </li>
</ul>  

DOM树中有如下四个节点:

ul  
ul>li  
ul>li>a  
ul>li>a>span  

那么对应的我们就可以设计出如下的 BEM class:

<ul class="menu">  
  <li class="menu__item">
    <a class="menu__link">
      <span class="menu__text"></span>
    </a>
  </li>
</ul>

是不是非常一目了然。当然 BEM 的教程和例子非常多,这里就不一一赘述了。

SMACSS(Scalable and Modular Architecture for CSS)

这个名字老长了,官方介绍是这样说的:

SMACSS (pronounced “smacks”) is more style guide than rigid framework.

不明觉厉。

开个玩笑,其实这个就和它的介绍一样,是一个指导性的小手册,大部分内容可以直接在网上读到。也有书可以买。说来惭愧我并没有读完这部分的内容,所以也就不强行解释一波了(实在太长了。。。)有兴趣的可以去网站看