天天看点

浅谈OOCSS、SMACSS、BEM三种设计模式与前端架构优化的关系

浅谈OOCSS、SMACSS、BEM三种设计模式与前端架构优化的关系

面向对象的OOCSS,是由Nicole Sullivan提出的css理论,虽说是理论,实则更像一种程序员约定的规范。

<div class="demo-list">

    <ul>

        <li><a href="#">...</a></li>

    </ul>

</div>

对a修改样式可能用.demo-list ul li a选择,效率比较低,另一方面一旦在后期过程中对列表html进行重构,css也需要重构,耦合性变得很强,维护困难。

OOCSS推荐的写法是在a标签加上demo-a样式,可以通过.demo-list .demo-a的方式来控制解耦。

提取公共样式很多框架都是这种模式,Bootstrap按钮.btn-info、.btn-warning等。

SMACSS通过一个灵活的思维过程来检查你的设计过程和方式是否符合你的架构,更像一种规范~

    1为css分类

    2命名规范

    3最小化适配深度

1为css分类

为css分类这一点是SMACSS的核心。SMACSS认为css有5个类别,分别是: 

1 Base 

2 Layout 

3 Module 

4 State 

5 Theme or Skin

SMACSS还约定了一个前缀l-/layout-来标识布局的class

.layout-header {}

.layout-container {}

.layout-sidebar {}

.layout-content {}

.layout-footer {}

SMACSS中的模块具有自己的一个命名,隶属于模块下的类皆以该模块为前缀

.todolist{}

.todolist-title{}

.todolist-image{}

.todolist-article{}

SMACSS状态规范,这个应该很多前端开发者都很好理解,描述的是任一元素在特定状态下的外观。

is-hidden

主题规范,描述了页面主题外观,一般是指颜色、背景图。Theme Rules可以修改前面4个类别的样式,且应和前面4个类别分离开来(便于切换,也就是“换肤”)。SMACSS的Theme Rules不要求使用单独的class命名,也就是说,你可以在Module Rules中定义.header{ }然后在Theme Rules中也用.header { }来定义需要修改的部分(后加载覆盖前加载样式内容)

2命名规范

按照前面5种的划分:

Base Rules(Pass)

Layout Rules用l-或layout-这样的前缀,例如:.l-header、.l-sidebar。

Module Rules用模块本身的命名,例如图文排列的.media、.media-image。

State Rules用is-前缀,例如:.is-active、.is-hidden。

Theme Rules如果作为单独class,用theme-前缀,例如.theme-a-background、.theme-a-shadow。

3最小适配深度

/* depth 1 */ .sidebar ul h3 { }

/* depth 2 */ .sub-title { }

两段css的区别在于html和css的耦合度(这一点上和OOCSS的分离容器和内容的原则不谋而合)。可以想到,由于上面的样式规则使用了继承选择符,因此对于html的结构实际是有一定依赖的。如果html发生重构,就有可能不再具有这些样式。对应的,下面的样式规则只有一个选择符,因此不依赖于特定html结构,只要为元素添加class,就可以获得对应样式。

当然,继承选择符是有用的,它可以减少因相同命名引发的样式冲突(常发生于多人协作开发)。但是,我们不应过度使用,在不造成样式冲突的允许范围之内,尽可能使用短的、不限定html结构的选择符。这就是SMACSS的最小化适配深度的意义。

BEM,即Block,Element,Modifier,是由Yandex(俄罗斯最著名的互联网企业)的开发团队提出的前端开发理论。BEM通过Block、Element、Modifier来描述页面(关键就是为了解决多人协作的命名问题)。

Block是页面中独立存在的区块,可以在不同场合下被重用。每个页面都可以看做是多个Block组成。

Modifier是描述Block或Element的属性或状态。同一Block或Element可以有多个Modifier。

在用 jQuery 可以常常看到这样的写法:$(‘.nav–main a’),一旦css发生重构,javascript代码也将变得难以维护,分不清那些代码是否会受到影响。

所以用 HTML 的属性去选取 DOM 节点会更好,如果非要用 CSS 的 class 那也可以多写一个 js- 的 prefix,以表示这个节点有被 Javascript 使用,例如:

<li><a class='nav-a js-nav-a'></a></li>

三种设计模式都有共同的特点,那便是让html与css更好的解耦,抽取样式中可复用的部分,使你的html代码更具语义。了解这些设计模式无疑会使css代码更具模块化,多人协作的时候也能有效避免那些命名问题带来的困扰又或者说提供一些解决的思路。最重要是提取精华,灵活应用,更加的规范规模化,在达到提高效率的同时兼顾性能。

继续阅读