OOCSS vs. OOSCSS

发布于 大漠

在这篇文章中我主要想给大家阐述在使用Sass来编写CSS和OOCSS两者之间的差异。在开始之前,我想在大家对定义语义化和演示(视觉)类名之间的差异有所了解。

语义化和演示(视觉)类名

  • 演示(Presentational):这里更趋向于将其称之为视觉类名,就是纯视觉。简单点说,视觉化类名是没有任何意思,就是根据视觉呈现的风格化,将其在HTML元素中声明类名。也就是说根据,视觉的表象,在HTML定义对应的类名,比如redbluemb10
  • **语义化(Semantic):**根据语义化在HTML中给元素定义类名。简单点说,就是根据功能模块,在HTML中定义类名,比如.user-registration或者.billing-info

既然声明类名有这样的方法,我们先不说哪种更好,哪种更不好。先来看看OOCSS的原则。

OOCSS基本原则

先来看看OOCSS基本原则中,认为比较好的方面:

  • 强调重用
  • 选择器简洁
  • 可扩展类
  • 强调风格与内容分离
  • 强调内容与容器分离

既然有好的一面,当然也不足的地方:

  • 大量使用演示类
  • 需要在模板中应用演示类
  • 样式(CSS)和结构(HTML)藕合太紧
  • 如果设计变动,需要更改CSS和HTML
  • 创建了数千行CSS,但有可能这些CSS永远不会被使用。比如Twitter Bootstrap

如果你从未接触过有关于OOCSS相关的概念或知识,我建议您先阅读一下下面几篇文章:

OOSCSS的基本原则

首先需要简单的解释一下OOSCSS的概念,其实它就是OOCSS的一个变异体,OOCSS是Object-Oriented CSS。那么大家也应该可以快速想到,OOSCSS其实就是Object-Oriented SCSS。其中SCSS是Sass的另一种语法版本。如果你没有接触过Sass,可以先点击这里进行了解或者学习。

既然OOCSS有一些基本原则,那么OOSCSS也避免不了这方面的俗套,来看看OOSCSS具有哪些基本原则:

  • 没有CSS,只有Sass
  • 通过%placholder来声明视觉对象
  • 可以通过mixin创建可重复的CSS
  • 语义化的类名在DOM中声明,而视觉化类名在Sass中声明
  • 否则不可能使用CSS构建UI结构和框架
  • 通过Sass来扩展类,而不是通过DOM来扩展类

可以确认的是,使用OOCSS可以解决其中的一些问题。毕竟在你的库中有一些像.ptn.pvn.pan等类名。并且提供一份简单的文档,告诉其他开发者他有这些可选项,告诉他们这些类表示的意思。对于其他开发者而言,他也可以在HTML模板文件中简单、快速的像下面这样用起来:

<!-- HTML -->
<div class="pan">
    ...
</div>

例如,我们需要给表单的label写一个样式。现在这个label有一些简单的样式:font-familyfont-sizecolormargin。我最初的想法是像下面这样写CSS:

/*CSS*/
.billing-info label {
    font-family: arial;
    font-size: 14px;
    color: #313131;
    margin-bottom: 10px;
}

如果你正在遵循设计规范,并且你没准备采用OOCSS的指南做类似的场景,这些很有意义,但它没有任何的可复用性。那么这些样式你需要复制和粘贴到其他的类名中。因此,有没有更好的方式?OOCSS这样说:

CSS可以像下面这样写:

/*CSS*/
.label-font-family {
    font-family: arial;
}
.larger-font-size {
    font-size: 150%;
}
.text-color {
    color: #313131;
}
.mbm,
.mvm,
.mam {
    margin-bottom: 10px !important;
}

此时,你的HTML模板需要像下面这样来写:

<!-- HTML -->
<fieldset>
    <label for="field" class="arial-font-family larger-font-size text-color mbm">Form Label</label>
</fieldset>

Wow, 太麻烦了。阿,你不想信我?那你看看Twitter Bootstrap按钮生成器

<!-- HTML -->
<a href="#" class="btn btn-success btn-large">
    <i class="icon-white icon-heart"></i> Bootstrap Button Generator
</a>

现在来说说OOSCSS

可伸缩,面向对象的CSS,绝对是一个很时髦的东东。

我们要讨论的例子是我们可以给HTML模板创建具有语义化的类名和使用Sass创建可复用的CSS对象。

<!-- HTML -->
<fieldset class="filling-info">
    <label for="text-field">
        ...
    </label>
</fieldset>

Sass创建的可复用的CSS对象:

//SCSS
%arial-font-family {
    font-family: arial;
}
%larger-font-size {
    font-size: 150%;
}
%text-color {
    color: #313131;
}
%mbm {
    margin-bottom: 10px !important;
}

.billing-info {
    label {
        @extend %arial-font-family;
        @extend %larger-font-size;
        @extend %text-color;
        @extend %mbm;
    }
}

在这个示例中,使用了Sass的一个新特性%placeholder。它允许开发者创建类似OOCSS中的视觉类名,它可以一直存在那,只有网页中其他的类名中通过@extend来调用,才会产生代码。比如这个示例中的.billing-info label

使用这个技术,当这些类名在.billing-info选择器扩展后,编译出来的CSS如下:

/*CSS*/
.billing-info label {
  	font-family: arial;
}

.billing-info label {
    font-size: 150%;
}

.billing-info label {
    color: #313131;
}

.billing-info label {
  	margin-bottom: 10px !important; 
}

让我们来探讨一下这个想法,如果有一个送货页面的label和上面的看起来一起,那么可以使用同样的方式扩展过去

// SCSS
.shiping-info {
    label {
        @extend %arial-font-family;
        @extend %larger-font-size;
        @extend %text-color;
        @extend %mbm;
    }
}

最后编译出来的CSS像下面这样:

/*CSS*/
.billing-info label,
.shiping-info label {
  	font-family: arial;
}

.billing-info label,
.shiping-info label {
    font-size: 150%;
}

.billing-info label,
.shiping-info label {
  	color: #313131;
}

.billing-info label,
.shiping-info label {
  	margin-bottom: 10px !important;
}

当我们想在页面其他部分使用这些OOCSS的%placeholder类会发生什么,像这样吗?

// SCSS
div {
  	&:first-line {
    	@extend %larger-font-size;
  	}
}

input {
  	&[type=text] {
   		@extend %mbm;
  	}
}

最后,我们得到的CSS像这样:

.billing-info label,
.shiping-info label {
  	font-family: arial;
}

.billing-info label,
.shiping-info label,
div:first-line {
  	font-size: 150%;
}

.billing-info label,
.shiping-info label {
  	color: #313131;
}

.billing-info label,
.shiping-info label,
input[type=text] {
  	margin-bottom: 10px !important;
}

其实扩展类的写法在CSS中是一直存在的。虽然说OOCSS不直接支持这种技术,但可以说OOSCSS是可以做到的。

事实开发中,最终还得你自己做出决定是否这样去编写你的CSS。但从我过去12年编写CSS的经验来说,Sass是编写可伸缩,可扩展、可管理的CSS库的最好方法。

本文根据@anotheruiguy的《OOCSS v OOSCSS》所译,整个译文带有我们自己的理解与思想,如果译得不好或有不对之处还请同行朋友指点。如需转载此译文,需注明英文出处:https://gist.github.com/blackfalcon/5255648

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。中国Drupal社区核心成员之一。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

如需转载,烦请注明出处:https://www.fedev.cn/preprocessor/oocss-vs-ooscss.html