Krasimir Tsonev在《Starting to Write CSS》(中文版本,请点击这里)让你领略了CSS其实也是有思想的,也很有意思的。虽然介绍的各种思想都很强大,但始终没有离开CSS的层面,而CSS却又是非常的脆弱。那么有没有办法,能否结合文中多个思想在一起。你思考过吗?如果你还没有思考并不要紧,今天我们一起跟随Takeshi Takatsudo写的PPT来领略一下OOCSS与Sass的结合。
在这篇文章,主要以两个按钮的制作,来探讨OOCSS的思想以及如何结合Sass更完美的实现。或者说,通过按钮的制作,一起探讨在Sass中如何使用OOCSS的思想。希望大家喜欢。
面向对像对于一位程序员来说并不会陌生,因为他成任何现代编程语言的一种基本形式,数据的抽象化、模块化和继承等特点在编写代码中得到了大规模的应用。而面向对象的CSS简称为OOCSS熟悉的人并不太多。面向对象的CSS是一种容易重用的一种CSS规则,也是OOP概念,从而降低了页面加载时间,提高网站性能。
OOCSS不是一个框架,也不是一种技术,更不是一种新的语言,他只不过是一种方法,一种书写方法。换句话说OOCSS其核心就是用最简单的方式编写最整洁,最干净的CSS代码,从而使用代码更具重用性,可维护性和可扩展性。
OOCSS咱们可以理解成为一种书写CSS的思想,而这种思想最关键的一点是如何在页面中识别,创建和模块化可重用的对像,并在页面中任何需要的地方重用,并扩展其附加功能。简单一句话概括:
OOCSS就是的确定对象,并给这个对象创建CSS样式规则
引用OOCSS之父Nicole Sullivan的话来说,OOCSS有两个原则:
这里我们就不在用过多的篇幅来阐述OOCSS,如果您对OOCSS感兴趣的话,大家可以点击早期分享的两篇文章《OOCSS概念》、《面向对象的CSS》。
前面说过,CSS总是脆弱的。我们应该寻找更强大的东西来代替CSS。接下来也就是我们今天最主要的一部分内容——OOCSS与Sass的结合。
接下来我们用一个简单的按钮示例来做为整篇文章的路线。首先我们有两个这样的按钮,如下图所示:
根据上图的效果,很多CSSer不经意定义出一个没有任何语意化的类名:
<a rel="nofollow" href="http://www.w3cplus.com/preprocessor/#" class="blackborder redbg">Twitter</a>
<a rel="nofollow" href="http://www.w3cplus.com/preprocessor/#" class="blackborder bluebg">Facebook</a>
两个具有黑色边框的按钮都定义了一个blackborder
的类名,用来控制按钮的边框,同时在红色按钮上添加了类名redbg
,在蓝色按钮添加了类名bluebg
。但定义这样的类名是否有考虑过,如果哪一天,页面的按钮边框不在是黑色,背景不在是红色和蓝色时候,你将又是如何考虑。所以说这样定义类名是你样式中的一大败笔。对于我个人而言,我是无法忍受的。
或许你也发现,这样命名类名也自己无法接受,想来想去,是要换点有语义化的类名,这样一来看到类名,就知道了按钮指的是什么按钮,于是就将前面的类名修改成了twitterbtn
和facebookbtn
:
<a rel="nofollow" href="http://www.w3cplus.com/preprocessor/#" class="twitterbtn">Twitter</a>
<a rel="nofollow" href="http://www.w3cplus.com/preprocessor/#" class="facebookbtn">Facebook</a>
类名已经有语义化了,接着我看这两个按钮的样式:
/*twitter button*/
.twitterbtn {
border:3px solid #000;
padding:10px 20px;
color:#fff;
border-radius:10px;
background:red;
}
/*facebook button*/
.facebookbtn {
border:3px solid #000;
padding:10px 20px;
color:#fff;
border-radius:10px;
background:blue;
}
从样式中,我们不难发现,两个按钮有很多样式都是一样的:
border:3px solid #000;
padding:10px 20px;
color:#fff;
border-radius:10px;
在CSS中,可以将这个样式称之为公用样式,或许你首先想到的是,将两个按钮公用样式提取出来,通过组合选择器来处理:
.twitterbtn,
.facebookbtn{
border:3px solid #000;
padding:10px 20px;
color:#fff;
border-radius:10px;
}
.twitterbtn{
background:red;
}
.facebookbtn{
background:blue;
}
根据OOCSS的原则,可以将按钮共同样式部分定义为一个对象btnbase
,并且将这部分相同的样式赋予给他。这样一来,将这个对像类名加到按钮标签中:
<a rel="nofollow" href="http://www.w3cplus.com/preprocessor/#" class="btnbase twitter">Twitter</a>
<a rel="nofollow" href="http://www.w3cplus.com/preprocessor/#" class="btnbase facebook">Facebook</a>
使用OOCSS之后,相同样式(此处称之为皮肤)赋予给对像btnbase
,在两个按钮中都可以调用这个对象btnbase
,并且重用他的样式:
.btnbase {
border:3px solid #000;
padding:10px 20px;
color:#fff;
border-radius:10px;
}
.twitter {
background:red;
}
.facebook {
background:blue;
}
按上面的方法,你已成功的将OOCSS运用到你的CSS中,或许你又会开始纠结:
<a rel="nofollow" href="http://www.w3cplus.com/preprocessor/#" class="btnbase twitter">Twitter</a>
<a rel="nofollow" href="http://www.w3cplus.com/preprocessor/#" class="btnbase facebook">Facebook</a>
添加对象类名btnbase
之后,他具有语义化吗?开始纠结中,也开始思考中…
相比之下,没有对象类名btnbase
:
<a rel="nofollow" href="http://www.w3cplus.com/preprocessor/#" class="twitterbtn">Twitter</a>
<a rel="nofollow" href="http://www.w3cplus.com/preprocessor/#" class="facebookbtn">Facebook</a>
上面的更具语义化,但是又脱离了OOCSS,真心的又纠结起来了…
纠结来纠结去,还是因为CSS离完美化太遥远,仅靠CSS自身几乎不可能做好每件事。既然CSS无法完美的解决,为何不考虑CSS预处理器Sass呢?可以使用@extend
来扩展CSS的类。
如果你对Sass有过了解,扩展CSS的类,在Sass中有两种方法都可以轻意实现:
首先使用Sass中的mixin
将按钮的公用样式定义一个@mixin btnbase
,然后通过@include
在各个按钮中调用这个mixin
:
//HTML
<a rel="nofollow" href="http://www.w3cplus.com/preprocessor/#" class="twitterbtn">Twitter</a>
<a rel="nofollow" href="http://www.w3cplus.com/preprocessor/#" class="facebookbtn">Facebook</a>
//SCSS
@mixin btnbase {
border:3px solid #000;
padding:10px 20px;
color:#fff;
border-radius:10px;
}
.twitterbtn {
@include btnbase;
background:red;
}
.facebookbtn {
@include btnbase;
background:blue;
}
如果你从未接触过Sass中的mixin
,个人强烈建议您阅读这篇文章《理解SASS的嵌套,@extend,%Placeholders和Mixins》。
编译出来的CSS:
.twitterbtn{
border:3px solid #000;
padding:10px 20px;
color:#fff;
border-radius:10px;
background:red;
}
.facebookbtn{
border:3px solid #000;
padding:10px 20px;
color:#fff;
border-radius:10px;
background:blue;
}
通过mixin
扩展出来的CSS类,编译出来的CSS并不完美,重复生成了一些相同的代码,对于有代码洁癖的同学是无法接受的。
熟悉Sass的同学都知道,实现类似上面扩展CSS类名功能,除了mixin
之外,还有一个@extend
。使用@extend
和mixin
基本类似,不同的是,直接在Sass中定义一个类名,然后通过@extend
来调用:
//SCSS
.btnbase{
border:3px solid #000;
padding:10px 20px;
color:#fff;
border-radius:10px;
}
.twitterbtn{
@extend .btnbase;
background:red;
}
.facebookbtn{
@extend .btnbase;
background:blue;
}
//编译出来的CSS
.btnbase,
.twitterbtn,
.facebookbtn{
border:3px solid #000;
padding:10px 20px;
color:#fff;
border-radius:10px;
}
.twitterbtn{
background:red;
}
.facebookbtn{
background:blue;
}
使用@extend
扩展类名较mixin
扩展类名,编译出来的CSS代码更干净,从而让你的样式文件体积也变得更小,性能更优。不过其有一个缺点就是,HTML
结构中并没有使用btnbase
类名,在样式中会生成这个类名。不过在Sass3.2中,可以使用%placeholder
修改这个问题,稍后会介绍这个东东。
上面分别介绍了CSS和Sass使用对象的方法,从中也看出他们略有不同,结合前面的内容,通过一张图更能向大家说明CSS和Sass中使用对象解析机制:
上图可以清晰的看出,在CSS中,对象都收集在样式中,并以一个类名定义,比如此例中使用了btnbase
,然后通过HTML中添加类名来扩展。也就是说需要HTML和CSS同时维护这个公用对象。而在Sass中,将公用对象收集在Scss文件中,并且直接在Scss文件中扩展对象,通过编译出新的CSS。也就是说只需要在Scss文件中维护和扩展公用对象。明显在Sass中使用面向对象要比在CSS中使用面向对象来得简单与方便。概括起来主要有以下几点:
那么我们在回过头来,在Sass中通过定义一个类名.btnbase
,并使用@include
调用.btnbase
,编译出来的CSS会有.btnbase
存在,无论这个.btnbase
是否在结构中调用都将存在。那么在Sass3.2中,我们可以使用%placeholder
来代替.btnbase
。这样一来,编译的CSS中.btnbase
将不会存在。
//SCSS
%btnbase {
border:3px solid #000;
padding:10px 20px;
color:#fff;
border-radius:10px;
}
.twitterbtn {
@extend %btnbase;
background:red;
}
.facebookbtn {
@extend %btnbase;
background:blue;
}
//编译出来的CSS
.twitterbtn, .facebookbtn {
border: 3px solid #000;
padding: 10px 20px;
color: #fff;
border-radius: 10px;
}
.twitterbtn {
background: red;
}
.facebookbtn {
background: blue;
}
将面向对象运向到Sass中,让你让明显的体会到CSS是多么的脆弱,就算是使用了面向对象,也会让你的代码增加一些额外的代码,而这些代码让你难易维护。而在Sass中却不一样,可以将面向对象(公用代码)提取出来,通过%placeholder
来定义(当然有很多时候也可以使用mixin
,比如要传参的时候),将在Sass中直接调用。这样避免在了HTML中通过扩展类名来调用公用部分(对象)。本文通过两个按钮的简单实例为路线,简单的介绍了OOCSS与Sass结合的强大力量与优势。希望这篇文章对大家会有所帮助。