流行的CSS思想之——浅析OOCSS
更新时间:2015年12月29日14时02分 来源:传智播客前端与移动开发学科 浏览次数:
——前言
随着Web技术的发展,每一个网站都离不开CSS(层叠样式表),它的出现将Web内容与表现(也可以称作结构与样式)做到了真正的分离,因此CSS已经成为前端开发人员的基础必备技能。
会用CSS的人都有这样一种感觉:它实在太简单了!没错,CSS的语法是最常见的键值形式(属性名:属性值),常用的样式属性也就那么几十种。在掌握了选择器、布局定位、盒模型以及常用的样式之后,编写一个漂亮的网站完全没有问题。当我们从新手变成老手做过无数漂亮网页之后,你是否有过这样的疑惑:那些常用的样式属性,我每天都要敲上几十遍甚至上百遍,它们难道就不能精简一下,解放双手给我腾出一杯coffee的时间吗?
答案是肯定的!学过后台开发语言的人应该知道:思想是灵魂,凌驾于代码之上;下面我们通过“流行的CSS思想”系列文章来了解一些当下正在流行的CSS思想。
OOCSS
定义:OOCSS(Object Oriented CSS)顾名思义,就是面向对象的CSS,让我们以面向对象的思想为指导,编写出可重用,可扩展,易维护的CSS样式,因此它不是一门新的编程语言或者技术,也不是新的语法,它只不过是一种书写CSS的方法和规范。
OOCSS的核心就是用最简单的方式编写最整洁,最干净的CSS代码,避免出现一锅粥式的杂乱无章(编写时麻烦,修改时头疼,改版维护时难于上青天)。
OOCSS最重要的是从项目的页面中分析抽象出“对象”组件,并给这些对象创建CSS规则,最后完善出一套基础组件库,then,我们新建页面时为元素应用已有的样式规则,只须重写少量的甚至不写任何样式,就能创建一个漂亮的页面,解放双手指日可待。
引用OOCSS之父Nicole Sullivan的话来说, 面向对象的CSS有两个原则:
独立的结构和样式(Separation Of Structure From Skin)
独立的容器和内容(Separation Of Containers And Content)
独立的结构和样式(皮肤): 几乎每个元素在同一页面上具有不同的视觉表现形式(即皮肤,例如:登录按钮的皮肤和退出按钮的皮肤),并在不同的页面上重复应用此皮肤样式。
把元素的结构样式和皮肤样式独立出来作为基础模块样式,这些模块样式可重用到任何其它元素并得到一致的显示结果。
在将结构和皮肤的样式分离之前,我们的CSS样式很可能会这样定义:
#button {
width: 200px;
height: 50px;
padding: 10px;
border: solid 1px #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}
#box {
width: 400px;
overflow: hidden;
border: solid 1px #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}
#widget {
width: 500px;
min-height: 200px;
overflow: auto;
border: solid 1px #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}
上面三个元素的样式是唯一的,并且它们用不可重用的ID选择器来定义各自的样式。但他们也有一些共同的样式属性,比如灰色的边框、阴影样式,随着一点点地分析与合并,我们最终会抽象出共同的皮肤样式:
.button {
width: 200px;
height: 50px;
}
.box {
width: 400px;
overflow: hidden;
}
.widget {
width: 500px;
min-height: 200px;
overflow: auto;
}
.skin {
border: solid 1px #ccc;
background: linear-gradient(#ccc, #222);
box-shadow: rgba(0, 0, 0, .5) 2px 2px 5px;
}
现在,所有的样式都使用类来定义。同时,我们将共同的样式提炼为一个可重用的“皮肤”,避免了那些不必要的自我重复。将“皮肤”样式应用于任何元素都可得到相同的视觉效果,这就是OOCSS所倡导的“通过尽量少的样式来编写高复用的CSS”。
独立的容器和内容:把内容从容器中分离出来,使内容不再局限于特定的容器,换句话说也就是使任何容器接受任何形式的内容。此原则关注的是对象的重用性(将模块的内容和容器解耦);
为了说明第二个原则的重要性,我们先看一段CSS:
#sidebar h3 {
font-family: Arial, Helvetica, sans-serif;
font-size: .8em;
line-height: 1;
color: #777;
text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}
这些样式将应用到#sidebar下的h3元素。但是,如果我们想把除了font-size和text-shadow之外所有样式应用到footer上面,如果你不使用OOCSS又该如何定义呢?
#sidebar h3, #footer h3 {
font-family: Arial, Helvetica, sans-serif;
font-size: 2em;
line-height: 1;
color: #777;
text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}
#footer h3 {
font-size: 1.5em;
text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
}
虽然上面这种方式不算优雅,却也算不上最坏的情况,纳尼?难道还有比这更糟的?! 是的,没有最糟,只有更糟:
#sidebar h3 {
font-family: Arial, Helvetica, sans-serif;
font-size: 2em;
line-height: 1;
color: #777;
text-shadow: rgba(0, 0, 0, .3) 3px 3px 6px;
}
/* other styles here.... */
#footer h3 {
font-family: Arial, Helvetica, sans-serif;
font-size: 1.5em;
line-height: 1;
color: #777;
text-shadow: rgba(0, 0, 0, .3) 2px 2px 4px;
}
你可能已经意识到,我们正在辛苦的进行着完全没必要的重复、重复、再重复。OOCSS鼓励我们从全局的角度去考虑不同的元素,然后将它们共同的属性样式抽象为对象或模块,从而可以在不同的地方重复使用。
上述的例子中,大量使用了后代选择器和ID选择器,这违背了OOCSS中“独立容器和内容”。因为后代选择器或ID使得内容过分依赖于特定的容器,后代选择器嵌套的越深,这种复杂性也就越严重。另外,div.header 或 h1.title类似的选择器也是不可取的,我们推荐的做法是直接使用.header和.title。
以下是OOCSS需要注意的关键点:
1. 尽量通过给基础组件添加多个类(扩展基础组件的CSS规则)的方式,来避免(父容器+组件类)这种后代选择器的使用,从而保持OOCSS的扩展性。
2. 时刻注意不要把基础组件搞成特定组件,组件是属于大家的、公共的,不要尝试私有化。
3. 样式类的定义尽量不依赖HTML结构和标签(不符合OOCSS第二个原则)。
4. 避免后代选择器(如:不要使用类似于.sidebar h3),尽量缩短后代选择器的长度,或者直接给元素添加相应的类(保持层次单纯,易于重构)。
5. 避免使用id作为CSS的选择器,坚持使用类!!(类可以使得样式表模块化,易于重用,ID选择器私有化严重,不利于重用,违背OOCSS思想)。
6. 避免在你的样式表中给类名附属一个元素名(如不要这样做div.header或h1.title)
7. 除非一些很少的情况,避免使用!important。
8. 使用CSS网格(栅格系统);