OOCSS:面向对象CSS的介绍

你听过“内容为王”这句话吗?身为一个web开发者,干着经常跟内容和创意打交道的工作,你应该深有体会。这句话总是被提及,但却是真理——访客就是这样被吸引来的。

然而,站在web开发者的视角,有些人却反驳说“速度才是王道”。久而久之,我也站在了这一边。近年来,很多资深的前端工程师通过一些优秀网站的性能测试,对于如何改善用户体验这一问题提出了他们的建议

不巧的是,太多的开发者(好心地)把重心放在JavaScript及其他方面的性能上,CSS似乎有点不受重视。

因此在本篇中,我将解决CSS这一被忽视的问题,引入面向对象的CSS这一概念,以及它如何帮助我们提高网页的性能和可维护性。

面向对象CSS的法则

跟其他面向对象编程方法类似,面向对象CSS的目的是鼓励代码重用,从而让样式表读取更迅速、更有效率,易于更新和维护。

面向对象CSS GitHub 维基页面所说, 有两个主要原则。

结构与皮肤分离

对于一个有样式的网页来说,几乎每个元素都有着不一样的视觉特征(也称“皮肤”),而这些皮肤在不同内容环境下却有重复。回想一下网站品牌识别元素(如颜色、细微的渐变以及可见边框等等)就知道了。另一方面,还有些平时不可见的特征(如“结构”)也是一直在重复使用。

当这些不同的特征被抽象成class模块,它们也就有了重用的可能,可以被应用于任何一个元素,效果相同。让我们来对比下改前改后的代码,你就能明白我所说的意思了。

在应用面向对象CSS原则前,你看到的CSS大概都长这样:

上面这3个元素是完全不同的,都是采用的不可重用的ID选择器,但它们的样式有很多是相同的。样式共有的情况经常出现在品牌设计或统一性设计中。
稍微整理一下,我们可以提炼出共有的样式,修改后CSS就会变成这样:

这样,所有的元素都是用class选择器,共有样式被合并为一个可重用的“skin”中,清除了不必要的重复。我们只需要把“skin”赋给所有需要的元素,则都会表现同样的样式,最终效果跟前一个案例一样,当然,后一种方法用更少、可重用的代码量解决了问题。

容器与内容分离

第二个原则则是将内容跟它们的容器分离。为了阐述这条的重要性,请看以下案例:

这些样式会被应用于#sidebar的所有子级h3元素,但如果要把它用在页脚的h3上,并赋予不同的字体尺寸和文本阴影的话,怎么办?
我们会这么做:

或者,情况有可能会更糟:

我们没必要地复制了样式,并且可能根本没意识到这一点(或者不在意)。而面向对象CSS,更鼓励人们在编程前预先想好不同元素间的共同点,把相同特征分离成模块或对象,以便在哪里都可以重用。
上面的案例中,样式都是使用继承选择器声明,无法重用,因为它们都被局限在一个特定的容器内(无论是sidebar还是footer)。
当我们遵守面向对象的法则,使用class模块搭建的话,我们可以确保样式不会依赖于任何容器元素。这也就意味着,无论结构及上下文是如何的,它可以在该文档中任意重用

真实案例

为了更好地说明面向对象CSS的使用方法,接下来我将以我的网站最新修改版为例子来解释。当我编码完内部header时,我意识到,内部header的基本结构样式可以被重用到本页其他元素上。

最开始设计header的时候的代码是这样的:

这里列出的一些样式是.header-inside元素特有的,但其他部分可以被提到模块中,以便重用。因此,我可以提炼结构型样式,放到重用的class中:

.globalwidth的样式包含以下几个属性:

  • 固定宽度
  • 外边距自动居中
  • 子元素相对定位
  • 左右内边距为20px
  • 溢出隐藏,清除浮动

现在,我们只需简单地附上该class,无需多写一行代码,就可以在任意你要的元素上使用这些样式了。

在我的站点中,我把基础内容和内部header元素重用了结构样式。依据我的设计稿,这些样式也可以应用到headercontent中水平导航元素中,亦或是任意符合“固定宽度”、“页面居中”的元素上。

加了globalwidth样式后,HTML就变成了这样:

有些人可能会觉得,这种“提取样式”的方式会把HTML搞得乱七八糟,并且跟把标记和展示效果分开的初衷是违背的。
但如果无视这些对HTML影响的争执,单看重用这3个元素的效果,没人能否认这样的方式确实能让开发者更容易追踪、修改共有的样式

媒体对象

Nicole Sullivan是面向对象CSS的开路者之一,她编写了一个叫媒体对象的可重用模块,她说,这可以帮助省下数百行的代码

媒体对象是能见识到面向对象CSS威力的极佳案例,它允许在它右边内置一个任意内容尺寸的媒体对象。即使某些用上的样式(甚至媒体元素本身)可能会有所变化,但媒体对象如果被赋予了基本共有样式,就能避免不必要的重复。

面向对象CSS的优势

上文里我已经陆续提及了面向对象CSS的优点,接下来我将展开讲:

访问更快

性能上的优势应该很明显了。如果你的样式越少、并CSS重复使用,你的CSS文件就能变得更小,这样浏览器就能更快地加载所有的资源。

确实,HTML文件会变大、也会显得比较乱。但有很多例子都反映出,HTML性能的那点损失,对于样式表性能的的大幅度提升来说,不足一提。

还一个必须记住的点,就是面向对象CSS就如同额外的性能礼物。也就是说,你每次重用CSS,都是在创建无需CSS代码的新样式元素。对于大型、高流量的项目来说,这些“礼物”都会是性能提升的关键因素

样式表可维护

有了面向对象CSS,你无需面对不断“繁殖”着的各式各样的样式表,取而代之的是一系列容易维护的模块,而在其中,自带天然的层叠功能充当重要作用。

当你为一个已有的站点添加新内容时,不需要再在样式表尾部添加任何新样式而不考虑该样式是否已存在。你可以重用已有样式,并在已有规则集的基础上扩展样式即可。

有了事先的思考,只用一点点代码开发整个页面是完全有可能的。任何已有的CSS模块可被视作所有新页面的基础元素,新的代码就能被压到最少。有些情况下,你甚至可以只用一行CSS来开发一整个样式满满的页面。

样式表可维护的优势也增强了它的稳健性。因为,样式都是模块,那么当一个新的开发者也要用样式表时,页面看上去也会是统一的。

还有些值得你关注

面向对象CSS已经引发了业界的热烈讨论,我试着打消一部分人共有的错误观念。

你仍然可以用ID

如果你决定只使用面向对象CSS的方式来开发,那么你的样式很大程度上以class为基础,你也不会使用ID选择器来给元素定义样式。

也就是因为这样,很多人错误地认为,面向对象CSS把ID抛弃了。这样说是不对的。

具体来说,避免使用ID的意思是,不在选择器上使用ID,而避开样式在HTML中把ID作为JavaScript钩子和碎片标识符却是完全正确的。

当然,你可能已经用ID定义了页面的一个特殊的元素,改用class可能会额外增加几字节大小。但即使是这样,我们还是认为,依靠class来排除未来可能出现的特异性问题,对你的页面来说更靠谱。

处理小型项目

对于小型的站点和app项目,你可能会觉得用面向对象CSS会有点浪费。所以,不要什么时候都把这篇文章作为辩解理由——还是得看项目来的。

尽管如此,我仍然认为这是个好的理念,至少,你可以时常想想它。一旦你掌握了窍门,我敢保证,你会发现开发大型项目变得灵活自如。

实战指导

入门面向对象CSS可能会比较费时,我仍在努力学习中,所以不见得能回答所有的问题。

但如果你想进入面向对象的思想模式,还是有一些忠告想分享给你:

  • 不要用派生选择器(如不要用.sidebar h3
  • 不要用ID来控制样式
  • 不要把元素和class相关联(如不要用div.header或 h1.title
  • 除非有特殊情况,不要用!important
  • CSS Lint来检查你的代码(搞清楚你出现的问题,以及解决方法
  • CSS网格系统

有些时候,肯定会打破一些规则,但总而言之,这些都是开发的好习惯,能让你的样式表更小、更易维护。

关注Nicole Sullivan进展

如果你想了解更多关于面向对象CSS的内容,那你最应该关注的就是Nicole Sullivan

除了时常更新博客,Nicole也制作了很多幻灯片,以供展示:

结论

很多人还无法接受面向对象CSS的理念,觉得它看上去跟许多我们已实践过的精华案例作对。但,一旦它的长期效益被接受,我敢保证,会有一大批的开发者转会的。

总而言之,面向对象CSS在开发中应该能有个不错的前景,这也督促所有开发者要开始考虑(至少在某些方面)跟其项目其他人员加强合作,让网页变得更快、更有效率、更易维护。

官方网站:An Introduction To Object Oriented CSS (OOCSS)

打赏支持我整理更多优质资源,谢谢!

打赏编辑

打赏支持我整理更多优质资源,谢谢!

任选一种支付方式

2 4 收藏

资源整理者简介:凝枫

非典型性程序员,爱做一些和写程序毫不相干的事 个人主页 · 贡献了46个资源 · 1


直接登录
最新评论

推荐关注

按分类快速查找

关于资源导航
  • 伯乐在线资源导航收录优秀的工具资源。内容覆盖开发、设计、产品和管理等IT互联网行业相关的领域。目前已经收录 1439 项工具资源。
    推送伯乐头条热点内容微信号:jobbole 分享干货的技术类微信号:iProgrammer