OOCSS vs. OOSCSS
在这篇文章中我主要想给大家阐述在使用Sass来编写CSS和OOCSS两者之间的差异。在开始之前,我想在大家对定义语义化和演示(视觉)类名之间的差异有所了解。
语义化和演示(视觉)类名
- 演示(Presentational):这里更趋向于将其称之为视觉类名,就是纯视觉。简单点说,视觉化类名是没有任何意思,就是根据视觉呈现的风格化,将其在HTML元素中声明类名。也就是说根据,视觉的表象,在HTML定义对应的类名,比如
red
、blue
、mb10
等 - **语义化(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-family
、font-size
、color
和margin
。我最初的想法是像下面这样写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。
如需转载,烦请注明出处:https://www.fedev.cn/preprocessor/oocss-vs-ooscss.html