第1章 Sass和Compass让样式表焕发第二春

第1章 Sass和Compass让样式表重焕青春

本章内容

  • 开始学习Sass和动态样式表
  • 用Sass更高效地写样式表
  • Compass简介
  • 用Compass迎接工程实践中的样式挑战

Sass是CSS3语言的扩展,它能帮你更省事地写出更好的样式表,使你摆脱重复劳动,使工作更有创造性。因为你能更快地拥抱变化,你也将敢于在设计上创新。你写出的样式表能够自如地应对修改颜色或修改HTML标签,并编译出标准的CSS代码用于各种生产环境。Sass引擎是用Ruby写的,对此你无需在意,除非要修改这个引擎的Ruby代码。

这本书适合两类读者,并尝试挖掘出他们之间的共同点。如果你发现自己两类都符合,那再好不过了。

对于Web设计师小伙伴们:你熟记着Adobe应用的各种快捷键,仅根据RGB值就能选出互补色。你或许(或许没有)戴着一副黑框眼镜,很可能用一杯咖啡或茶和最新的Smashing Magazine开始新的一天。你十分了解jQuery很危险,却不明白为什么开发小伙伴会笑你把CSS当做一门语言。

我们将帮你摆脱这些繁冗乏味的琐事,让你做最擅长的事——创新。我们知道你对样式重置、排版比例、颜色调节以及布局很有想法。我们将向你展示怎样通过更少的重复劳动,更快地写出样式表。从此,你将在图形软件上费时更少,而在样式表上做得更多。

对于前端开发同学:你们能够在Photoshop设计稿上切图,然后转化为语义化的HTML和CSS。但是有个问题,你的服务端模板那么符合DRY原则,即“别做重复劳动”(Don't Repeat Yourself),但你的样式表也太不符合这个原则了吧!而且,随着项目规模的增长,你发现组织样式表成了一大挑战。要是能像写项目中其他代码那样,使用变量、可复用模块以及控制语句来写样式表就好了。别担心,Sass正好满足了你的需求。

本章将介绍Sass的强大特性,比如选择器嵌套、变量、混合器、选择器继承,以及Compass怎样利用这些特性构建可复用的设计模式,从而使你摆脱重复性的体力劳动,专注于设计样式而不是实现样式。如果你还没有安装Sass,请参照附录A中给出的步骤安装Sass。如果你正在咖啡馆用iPad阅读本书,那仍然可以在线运行那些基本示例:http://Sass-lang.com/try.html

1.1 开始学习Sass

在开始研究示例之前,有必要明确几点。Sass既不是银弹也不是精灵粉。它不能帮你立刻选出颜色,做好排版和布局,但能帮你更快地实现你的想法并减少麻烦。在开始学习语法和特性之前,先看一下工作流的概况图。使用Sass时,Sass引擎将你的样式表源文件编译成100%纯CSS,如图1-1所示。 图像说明文字

图1-1 Sass编写和编译的工作流

从命令行到服务端集成框架,再到图形用户界面(GUI)工具,虽然有各种选择来运行Sass引擎,但这一工作流中的关键环节是输出CSS。然后你可以像平常那样部署静态的CSS文件,而Sass的语言特性使你能更快地写出具有高可维护性的CSS代码。

1.1.1 从CSS到Sass

如果你精通CSS,很快就能上手Sass。Sass更专注于怎样创造优雅的样式表,而非其内容。我们会介绍一些为你提供CSS最佳实践的工具(如Compass),不过归根结底,如果你拥有扎实的CSS基础即能从本书中获益匪浅。在计算机领域,错进,错出(garbage in, garbage out)原则总是成立的。如果你需要一本CSS入门书,请参阅Manning出版的Hello! HTML5 and CSS3

Sass支持两种语法。最初的缩进式语法使用.sass作为文件扩展名,且这种语法对空格敏感,所以选择器下面的属性要有缩进,而不用花括号括起来。每个属性之间通过换行来分隔,而不是分号:

h1
  color: #000
  background: #fff

SCSS即Sassy CSS在Sass 3.0中被引入,它是CSS3的超集。SCSS文件使用.scss作为文件扩展名,且到处都是熟悉的花括号和分号。

h1 {color: #000; background: #fff}

以上展示了这两种语法的主要不同,其他的不同点在附录C中讨论。

这两种语法Sass都会继续支持。你甚至可以在同一个项目中混合使用,只要不在同一个文件中使用即可。选择一种对你和你的团队而言适合的语法是很重要的。如果你周围的人都用Python或Ruby,那么可能空格敏感的缩进式语法会很适合。如果你的团队与外面的设计机构做生意,那么使用Sassy CSS将更容易成功。

除了学习CSS技巧和掌握Sass语法,以动态的思维去看待样式表也很重要。

1.1.2 动态思维

现在除了简单的说明书式的网站,谁还会去写很多静态的HTML?你把HTML文件以模板的形式提供给博客引擎、内容管理系统(CMS)或应用程序的框架去做预处理,然后动态地“填入”标签和内容。这些工具为HTML注入了生命,我们无法想象没有它们互联网将会变成怎样。所以你为什么还要再写静态的样式表呢?你将会看到那些被用来动态创建静态标签的特性,也可以用来动态创建静态样式表。何为动态创建静态样式表?意思即:当你写样式表时,不再受限于浏览器是怎样理解样式表的。通过条件判断、可复用的代码片段、变量以及其他的各种工具,你能够让样式表活起来。改变一个网站的布局和颜色风格变得如此简单,只要稍微调整一些变量就可以了。当然,虽然Sass允许你以一种时髦的方式来动态地写样式表,但产出的依旧是100%静态的CSS。一旦你开始使用动态样式表来工作,就能遵循内心深处一直呐喊的声音“别做重复劳动”。

1.1.3 别做重复劳动

Sass为样式表的作者提供了强大的工具,帮他们摆脱在写CSS时那些一遍又一遍的乏味劳动。Sass的很多特性都信奉广为流传的编程格言“别做重复劳动”,让你既能在写样式表时减少重复劳动,又能减少编译出的样式表中的冗余。创建样式表时,重复就是一种危险信号。你应该时常问自己:我怎样更高效地工作,而不仅仅是更卖力?接下来几节将向你展示怎样使用Sass来提升样式表的可复用性。

1.2 Sass你好:消除样式表冗余

写到这里我们已经唠叨很多遍“别做重复劳动”了。那么充满冗余的样式表是什么样的呢?请看代码清单1-1中的CSS。

代码清单1-1 一个需要消除冗余的糟糕样式表

h1#brand {color: #1875e7}

#sidebar {background-color: #1875e7}

ul.nav {float: right}
ul.nav li {float: left;}
ul.nav li a {color: #111}

ul.nav li.current {font-weight: bold;}
#header ul.nav {float:right;}
#header ul.nav li {float:left;margin-right:10px;} #footer ul.nav {margin-top:1em;}
#footer ul.nav li {float:left;margin-right:10px;}

即使是这样一个极其简单的例子,但显而易见还是有很多重复劳动。如果市场团队想要把那可爱的蓝色阴影从#1875e7调整成#0f86e3,将会发生什么?当然,只有两处修改的话还是可控的,但如果有十几处或更多处修改散落在不同的文件当中,那么“查找/替换”这种方式就会显得很原始,不是吗?另外,8个ul.nav在只有10行的样式表中也显得太多了。

在接下来的小节中,你将会学到一些写起来犹如夏日微风般惬意的语法糖,它们将会帮你摆脱样式表中的重复劳动,它们包括变量、混合器、选择器嵌套以及选择器继承。如果你觉得学习进度太快了,别怕,第2章会深入介绍每个概念。

1.2.1 通过变量来复用属性值

你是否在样式表中用过“查找/替换”来修改十六进制的颜色值?使用Sass,你可以把属性值赋给变量,然后在一个地方管理散落在各处的属性值,几乎任意属性值都可以赋给变量,比如颜色,边框大小:

$company-blue: #1875e7;
h1#brand {
  color: $company-blue;
}
#sidebar {
  background-color: $company-blue;
}

变量名以$符号开头,可包含所有可用作CSS类名的字符,包括下划线和中划线。在这个简单的例子中,如果你想要微调蓝色阴影,只需要修改变量赋值的那一处地方,使用变量的其他地方就会自动更新。

如果你有开发背景,会对变量感觉自然而然。如果你只有设计背景,第一眼看到变量可能会觉得有点陌生。但它真的不是什么新鲜事物。你已经在CSS中使用过很多有名字的属性值,比如bluegreeninheritblockinline-blockserif以及sans-serif。把变量想象成这些特殊的属性值。接下来,我们将展示怎样使用选择器嵌套来创建多层级的选择器,从而减少你的敲写工作。

1.2.2 使用嵌套来快速写出多层级的选择器

先给你讲个故事。有个得克萨斯人,他的工作是画出高速公路中间的虚线。第一个星期他是做得最好的那个,画了10英里。但接下来工作成果迅速降低,第二个星期他画了五英里,第三个星期只画了两英里,第四个星期只画了可怜的一英里。主管问他遇到了什么困难。他回答道:“哎,回到桶边的距离总是变得越来越远。”

这感觉正像使用多层级的选择器。请看下面的CSS:

ul.nav  {float: right}
ul.nav li {float: left;}
ul.nav li a {color: #111}
ul.nav li.current {font-weight: bold;}

Sass能帮你减少一些重复劳动。在第1章的代码示例文件夹中找到文件。1.1.2.nesting.scss,或者将代码清单1-2保存为一个文本文件,创建你自己的代码文件。

代码清单1-2 嵌套CSS的选择器

ul.nav {
  float: right;
  li {
    float: left; 
    a{
      color: #111;
    }
    &.current {
      font-weight: bold;
    }
  }
}

在终端中运行如下sass命令,并传入文件的路径:

Sass 1.2.nesting.scss

你将会在终端输出中得到如代码清单1-3所示的CSS结果。

代码清单1-3 通过使用选择器嵌套生成的CSS

ul.nav {
  float: right; }
  ul.nav li {
    float: left; }
    ul.nav li a {
      color: #111; }
    ul.nav li.current {
      font-weight: bold; }

除了格式上的一些不同,它跟我们一开始的CSS是相同的。(别在意目前的格式,后面会讨论更多输出选项。)

使用Sass,你可以将规则嵌套起来,并避免在选择器中重复写相同的元素。这不仅节约了时间,还有一个好处是,如果你稍后要把ul.nav从一个无序列表改成有序列表,你只需要修改一处。这个例子中的最后一个选择器原理相同。&符号是父选择器。在这个例子中,&.current相当于li.current。如果将来li改成了其他的元素标签,在这个元素内的current类依然命中这里的样式。现在你已经见过了怎样使用变量来复用属性值,怎样使用嵌套来写多层级的选择器,接下来让我们一鼓作气,看看混合器。

1.2.3 使用混合器来复用一段样式

变量使你能够复用属性值,但如果你想要复用一大段规则呢?传统的做法是,如果在样式表中发现重复,就会把公共的规则抽离出来放到新的CSS类中。

代码清单1-4 传统的CSS重构

ul.horizontal-list li {
  float: left;
  margin-right: 10px;
}
#header ul.nav {
  float: right;
}
#footer ul.nav {
  margin-top: 1em;
}

接下来你需要给元素ul.nav添加额外的类名horizontal-list。这种方式能够有效地工作,但如果你想要使类保持语意的同时依旧可复用,怎么实现呢?

打开1.1.2.mixins.scss,或者自己创建一个新文件,代码清单1-5是第二个例子。

代码清单1-5 通过使用@mixin@include重用代码

@mixin horizontal-list {
  li {
    float: left;
    margin-right: 10px;
  }
}
#header ul.nav {
  @include horizontal-list;
  float: right;
}
#footer ul.nav {
  @include horizontal-list;
  margin-top: 1em;
}

顾名思义,Sass混合器用于将一些规则混入到别的规则当中。使用@mixin命令,你可以将水平列表的规则抽取出来放到一个合适的命名混合器中。然后使用@include命令,将这些规则引入进来。因此你不再需要.horizontal-list类,因为那些规则已经被混入到ul.nav的规则当中,输出的CSS如代码清单1-6所示。

代码清单1-6 混合器帮助你消除冗余代码

#header ul.nav {
  float: right;
}
#header ul.nav li {
  float: left;
  margin-right: 10px;
}
#footer ul.nav {
  margin-top: 1em;
}
#footer ul.nav li {
  float: left;
  margin-right: 10px;
}

更便利的是混合器和变量的结合,这才是混合器的强大之处;也就是说,能够根据参数来决定使用的样式,从而使混合器更具可复用性。举个例子,假如你想要修改水平列表每个条目之间的间距,怎么使用混合器快速实现呢?找到代码示例1.1.2.2.mixins-parameters.scss,按照代码清单1-7对它进行修改。

代码清单1-7 在混合器中应用变量

@mixin horizontal-list($spacing: 10px) {
  li {
    float: left;
    margin-right: $spacing;
  }
}
#header ul.nav {
  @include horizontal-list;
  float: right;
}
#footer ul.nav {
  @include horizontal-list(20px);
  margin-top: 1em;
}

OK,我们给混合器添加了一个参数$spacing,其默认值为10px。参数这一概念跟我们之前看到的变量没有什么不同。在这个例子中通过使用默认值,头部的水平导航列表就得到默认的间距。在底部的导航列表中,通过传入值20px,从而增加列表元素之间的间距,输出的CSS如代码清单1-8所示。

代码清单1-8 通过使用混合器生成的最终CSS

#header ul.nav {
  float: right;
}
#header ul.nav li {
  float: left;
  margin-right: 10px;
}
#footer ul.nav {
  margin-top: 1em;
}
#footer ul.nav li {
  float: left;
  margin-right: 20px;
}

混合器能够让你复用一段属性,从而为你节省大量时间。不过聪明的读者或许发现了输出的样式表中有冗余,这是因为混合器在每一个被包含进来的地方,都会就地复制一段样式。别担心,Sass总留有一手。选择器继承就可以解决这个问题。

1.2.4 使用选择器继承来避免重复属性

如你所见,混合器能够在手写的样式表中有效地避免重复。但是,因为规则都混入到其他类中,所以在输出的样式表中不能完全避免重复。因为输出的CSS文件大小很重要,于是Sass引入了另一种稍微有点复杂的方式,让输出的CSS完全避免重复。选择器继承的意思就是让一个选择器能够复用另一个选择器的所有样式,但又不重复输出这些样式属性。看个例子你就明白了,比如,为表单的错误信息设置一些样式。

代码清单1-9 修饰错误信息的CSS

.error {
  border: 1px #f00;
  background: #fdd;
}
.error.intrusion {
  font-size: 1.2em;
  font-weight: bold;
}
.badError {
  @extend .error;
  border-width: 3px;
}

通过选择器继承,可以让.barError继承父类.error,也就是复用父类的所有样式,编译输出的结果如代码清单1-10所示。

代码清单1-10 通过选择器继承减少冗余

.error, .badError {
  border: 1px #f00;
  background: #fdd;
}
.error.intrusion,
.badError.intrusion {
  font-size: 1.2em;
  font-weight: bold;
}
.badError {
  border-width: 3px;
}

在这个例子中,同时定义了errorbadError类是有意义的,因为两者都需要在HTML中使用,但有时父类并不需要在HTML中使用。于是在Sass 3.2中引入了占位选择器,它支持在使用选择器继承的同时,不编译输出HTML中并不使用的父类,如代码清单1-11所示。

代码清单1-11 在选择器继承中使用占位选择器

%button-reset {
  margin: 0;
  padding: .5em 1.2em;
  text-decoration: none;
  cursor: pointer;
}
.save {
  @extend %button-reset;
  color: white;
  background: #blue;
}
.delete {
  @extend %button-reset;
  color: white;
  background: red;
}

占位顾名思义,继承了%button-reset的选择器在输出的CSS中占据了%button-reset的位置,如代码清单1-12所示。

代码清单1-12 通过选择器继承最终生成的CSS

.save, .delete {
  margin: 0;
  padding: .5em 1.2em;
  text-decoration: none;
  cursor: pointer;
}
.save {
  color: white;
  background: #blue;
}
.delete {
  color: white;
  background: red;
}

占位选择器能把常用的样式保存到一处,且不影响任何一个类名,使你能够放心使用。当然如果一个占位选择器没有被继承,其中的样式就不会被编译到CSS当中,以减少生产环境中样式表的无用样式,使其更小。

只需要一点小小的规划,选择器继承就能够让你摆脱写Sass代码时的重复劳动,并让输出的CSS文件保持整洁。现在你已经看到Sass怎样帮你避免重复劳动了,下一节将介绍Compass的功能。

1.3 Compass是什么

简单来说,Compass是一个强大的Sass框架,它的设计目标是顺畅、高效地装扮互联网,使用它的人可写出可维护性更高的样式表,而它已被授权给由设计师和开发者组成的社区来共同构建和分享。互联网应用的开发框架有很多,比如Rails就是面向Ruby的一个框架,类似地,Compass就是面向Sass的一个框架,它有一套实用的工具,并在长期的实战中总结出了最佳实践。

Compass由三个主要部分组成:混合器和实用工具的类库,能够集成到应用开发环境中的开发系统,以及一个用于构建框架和扩展的平台。让我们将本章之前提到的工作流概况图扩展一下,如图1-2所示,我们可以看到Compass如何融入到你的开发工作流中。

图像说明文字

图1-2 Compass工作流

1.3.1 Compass库

Compass自身包含了很多由Sass混合器和函数构成的模块,所有的这些模块在Compass的官网上都有详细的说明和示例。这些库会帮助你解决跨浏览器兼容问题,以及提供给你很多已经被证明过的优秀设计模式,比如说重置、网格布局、列表样式、表格辅助器和垂直韵律等。Compass同时提供了CSS3的帮助函数,帮你填充厂商前缀、抽离不同浏览器在实现同一CSS3属性时的不同,并让你写起CSS3属性来更得心应手。

Compass能非常灵巧地完成一些任务,比如说直接从文件系统读取你的图片然后输出对应的样式到你的CSS中。资源URL辅助函数让你能够轻松地切换到使用CDN网络进行项目部署,而无需重写你的样式引用。Compass甚至能自动帮你把同一目录的图片合成精灵图,帮你计算好单个图片的引用位置并自动输出到CSS文件中。

以上的任务你都可以通过自己的方式完成,但是经由设计社区验证的Compass方案能让你在更短的时间内完成更多的任务。

Compass的核心样式框架并不能让你的网站更美。实际上,所有的核心框架的特性都是独立于设计的,以便你能在任何风格的网站设计中使用。像所有的流行事物一样,网站的设计美学也在不断地过时和更新。所以提供精心设计的网站这个任务就留给了Compass社区的前端开发人员和设计人员,通过使用Compass的插件来实现。

1.3.2 简单的Compass样式项目

Sass和Compass都是用Ruby写的且起源于Ruby on Rails社区,但是Compass提供了工具和配置项,使在不基于Ruby的项目中编写Sass样式表也非常简单。无论你只是简单地写个html文件,还是把Sass集成到大型框架(比如Django、Dral或者.NET),Compass都能胜任。

Compass明白你不单单是在写样式,你是在构建设计。正因为如此,Compass需要知道你在哪里存放图片、字体和JavaScript文件,以便轻松管理并在样式中引用这些文件。举例来说,Compass会自动帮你构建精灵图,并在CSS中正确引用它们;假如你通过image-url()辅助器引用了一个并不存在的图片,Compass会告警;Compass可以在你的CSS中内嵌必要的图片和字体,免去浏览器的一些工作。

图像说明文字

图1-3 一个标准的Compass项目

1.3.3 社区生态系统

如果你有多年的Web开发经验,一定忘不了JavaScript框架诞生之前的黑暗日子。那真是一个可怕的时期——DOM上一个最小的诡异问题都要耗费你几个小时去排查。而现如今,JavaScript框架帮你解决了浏览器之间不一致的问题,并形成了一套基础的封装,让你的代码可以轻松移植到别人的项目上。多亏了Web开发社区辛苦努力的付出,现在用JavaScript开发简直就是一种享受。

作为Sass的一个框架,Compass致力于为开发者和设计人员提供一个基础架构,从而分享他们的库和框架,为大家参与开源样式开发推力助航。以前,分享一段CSS代码必须在博客文章中内嵌一段代码和示例文件,这样的日子正快速逝去,那种策略还有一个很大的弊端就是:随着时间的流逝,这段代码的作者很难再去解决bug或者增加新的功能。而有了Compass,样式库可以像其他软件一样分发,这就意味着修复bug或者添加对最新浏览器的支持无非就是升级和重新编译你的样式表。

很多社区成员会把他们的很多代码提炼打包到Compass中封装,然后供其他人直接使用,避免其他人在写静态CSS代码时还得重新编写复杂嵌套的代码(第10章会介绍如何编写你自己的Compass组件)。响应式布局、段落比例、自定义动画、精美的按钮、图片元素集,以及色板都可以通过Sass来编写,然后扩展到Compass中。利用Compass扩展,就无需构建无聊的基础代码,从而把更多的精力用于实现网站的独特功能。在你从Sass初学者向专家过渡的过程中,如果你一如既往地认可和感谢Sass、Compass和社区所做的工作,那么作为回报,你可以把你的辛苦工作成果分享给其他人。

1.4 创建一个Compass项目

如果你还没有安装Compass,可以参考附录A的指引进行安装。安装好以后,第一件事就是创建一个Compass项目。

同其他优秀的命令行接口工具(CLI)一样,Compass提供了非常丰富的帮助信息来帮我们了解Compass的各项功能。测试一下Compass是否安装成功。打开命令行进入一个新的样式项目目录,运行compass help。如果成功打印出了帮助信息和命令行参数信息,说明Compass安装好了。如果没有的话,请重新按照附录A的指引进行安装,然后重新尝试。

下面从创建一个新的Compass项目开始,新项目包含了一个配置文件和Sass源文件、CSS输出文件等。将该文件命名为sample

compass create sample

新目录下会生成这么几个文件:

total 8
drwxr-xr-x  6 wynn  staff  204 Jan  3 12:11 .
drwxr-xr-x  3 wynn  staff  102 Jan  3 12:12 ..
drwxr-xr-x  4 wynn  staff  136 Jan  3 12:11 .Sass-cache
-rw-r--r--  1 wynn  staff  315 Jan  3 12:11 config.rb
drwxr-xr-x  5 wynn  staff  170 Jan  3 12:11 Sass
drwxr-xr-x  5 wynn  staff  170 Jan  3 12:11 stylesheets

使用默认配置,Compass已经帮我们默认生成了一个config.rb配置文件,一个名为sass的目录,里边存放Sass的源文件,一个名为stylesheets的目录,里边存放Sass编译后生成的CSS文件。如果你想了解config.rb里边的所有配置项,请参考附录B。现在我们将使用默认配置来演示如何用Compass解决实际工作中遇到的CSS问题。

1.5 使用Compass解决真实的CSS问题

你已经知道了如何使用Compass创建一个基本的项目,接下来我们看看如何使用Compass应对我们几乎每天都面对的样式挑战。接下来的几小节将通过使用Compass的内置模块(Sass的函数和其他的特性组合而成)来实现CSS重置、网格布局、表格格式化和CSS3的一些特性。

1.5.1 通过重置来保持样式表现一致

通过Eric Meyer和其他的一些倡议者的努力,在开始创建样式之前添加一个重置文件已经变得非常普及。如果你曾经使用过CSS网格布局框架,里边就包含了CSS重置,只是你不知道而已。CSS重置无非就是把浏览器对于各种元素添加的CSS属性去掉,给开发者提供一个完全无干扰的开始来添加你想要的样式。

Eric的经典重置样式如代码清单1-13所示。

代码清单1-13 经典CSS重置

/* v1.0 | 20080212 */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
  margin: 0;
  padding: 0;
  border: 0;
  outline: 0;
  font-size: 100%;
  vertical-align: baseline;
  background: transparent;
}
body {
  line-height: 1;
}
ol, ul {
  list-style: none;
}
blockquote, q {
  quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
  content: none;
}
/* 不要忘了定义focus样式! */
:focus {
  outline: 0; 
}
/* 记得通过其他修饰方式来突出新插入内容! */
ins {
  text-decoration: none;
}
del {
  text-decoration: line-through;
}
/* 同时需要在表格元素标签上添加 "cellspacing=0" */
table {
  border-collapse: collapse;
  border-spacing: 0;
}

你或许已经注意到Compass项目默认生成的screen.css文件了,这个文件就是基于Erics的reset脚本衍生出来的。只要通过以下代码添加它,就可以让你的样式在各个浏览器里边起点一致:

@import "compass/reset"

就这一条命令,其实干了很多事情,我们一条一条来说。你通过使用Sass的引入命令@import引入Compass的重置模块。一个模块就是Compass框架中独立的一部分,可被随意引用添加到你的项目中。通过加入这行代码,你生成的CSS文件中就会包含CSS重置部分代码,如代码清单1-14所示。

代码清单1-14 通过引入CSS重置生成的文件

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
  margin: 0;
  padding: 0;
  border: 0;
  outline: 0;
  font-weight: inherit;
  font-style: inherit;
  font-size: 100%;
  font-family: inherit;
  vertical-align: baseline;
}
body {
  line-height: 1;
  color: black;
  background: white;
}
ol, ul {
  list-style: none;
}
table {
  border-collapse: separate;
  border-spacing: 0;
  vertical-align: middle;
}
caption, th, td {
  text-align: left;
  font-weight: normal;
  vertical-align: middle;
}
q, blockquote {
  quotes: "" "";
}
q:before, q:after, blockquote:before, blockquote:after {
  content: "";
}
a img {
  border: none;
}

大多数Compass模块并不会无故在你的样式表中添加样式,不要让CSS重置模块误导了你,Compass重置模块位于样式表的前边,只要被引入就会执行global-reset这一混合器。这个混合器的写法如代码清单1-15所示。

代码清单1-15 CSS global-reset 混合器

@mixin global-reset {
  html, body, div, span, applet, object, iframe,
  h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  a, abbr, acronym, address, big, cite, code,
  del, dfn, em, font, img, ins, kbd, q, s, samp,
  small, strike, strong, sub, sup, tt, var,
  dl, dt, dd, ol, ul, li,
  fieldset, form, label, legend,
  table, caption, tbody, tfoot, thead, tr, th, td {
    @include reset-box-model;
    @include reset-font; }
  body {
    @include reset-body; }
  ol, ul {
    @include reset-list-style; }
  table {
    @include reset-table; }
  caption, th, td {
    @include reset-table-cell; }
  q, blockquote {
    @include reset-quotation; }
  a img {
    @include reset-image-anchor-border; } }

这里我们注意到Compass使用了之前提到过的Sass的@mixin混合器和@include包含特性来构建reset模块。在global-reset之外,reset模块还提供了一系列有特定用途的重置混合器,其中有一个是专为HTML5元素服务的。通过在你的Sass文件中添加@include reset-html5命令,输出文件中会生成额外的CSS规则来对HTML5的元素进行基本的样式修改,如代码清单1-16所示。

代码清单1-16 使用了HTML5重置模块的输出代码

article, aside, canvas, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary {
  margin: 0;
  padding: 0;
  border: 0;
  outline: 0;
  display: block;
}

如果你想了解更多的Compass模块,请访问Compass官网查看在线文档。现在你已经熟练掌握了重置模块,接下来我们看看如何使用Compass的网格布局框架来更加高效地编写CSS。

1.5.2 不用计算创建布局

这几年CSS的主要趋势就是越来越流行网格框架,比如说Blueprint和960网格系统(如图1-4所示)。网格布局奠定了好的平面设计的基础,在这些年发展的愈发成熟。你只需在布局中选择特定数量的列,每列之间的内容自然会被统一地间隙隔开。

图像说明文字

图1-4 960px宽的网格系统布局

一般来讲,有了网格布局框架,在写一个优良的列式布局时就无需进行计算。框架通过CSS规则帮你设置好容器元素的宽以及在容器内的每个子列的宽。让我们看一下Blueprint框架里边的脚本是如何写的,如代码清单1-17所示。

代码清单1-17 Blueprint网格布局

.container {
  width: 950px;
  margin: 0 auto;
}
/* 建立基本的格式浮动和外间距. */
.column, .span-1, .span-2, .span-3, .span-4, .span-5,
.span-6, .span-7, .span-8, .span-9, .span-10, .span-11,
.span-12, .span-13, .span-14, .span-15, .span-16,
.span-17, .span-18, .span-19, .span-20, .span-21,
.span-22, .span-23, .span-24 {
float: left;
  margin-right: 10px;
}
/* 一行中的最后一列需要添加这个类修饰. */
.last { margin-right: 0; }
/* 通过使用下边这些类来设定列宽. */
.span-1 {width: 30px;}
.span-2 {width: 70px;}
.span-3 {width: 110px;}
.span-4 {width: 150px;}
.span-5 {width: 190px;}
.span-6 {width: 230px;}
.span-7 {width: 270px;}
.span-8 {width: 310px;}
.span-9 {width: 350px;}
.span-10 {width: 390px;}
.span-11 {width: 430px;}
.span-12 {width: 470px;}
.span-13 {width: 510px;}
.span-14 {width: 550px;}
.span-15 {width: 590px;}
.span-16 {width: 630px;}
.span-17 {width: 670px;}
.span-18 {width: 710px;}
.span-19 {width: 750px;}
.span-20 {width: 790px;}
.span-21 {width: 830px;}
.span-22 {width: 870px;}
.span-23 {width: 910px;}
.span-24 {width:950px; margin-right:0;}

使用以上这些CSS规则,通过在容器元素上添加container类,并在你希望放置在容器内的子元素上添加span-xx类,就可以创建出一个16列的布局。通过这样的方式进行布局,你能够快速地构建出原型,且不用记住在30和950之间的40的倍数。

那么Compass做了哪些事情来优化提升CSS网格布局呢?首先Compass以混合器的形式提供了对网格框架样式的支持,这样做的好处是按需使用,避免你的HTML标签需要添加额外的类名。其次,也是最重要的,Compass对网格布局的支持方式即是对其他框架的方式改进,这将在第4章详细介绍。

我们通过Blueprint创建一个Compass工程,在命令行中运行下面的命令:

compass create my_grid --using blueprint

就像在1.4节里边那样,你会在my_grid目录下找到一个全新的Compass工程,只是这次screen.scss文件的内容更多。这个文件有着详细的注释,且在一系列基本布局的样式里边,你可以看到有一个Blueprint模块快速的总览。首先映入眼帘的恐怕是列式布局相关的样式被归类成了混合类,所以不是在HTML标签上添加一个span-8的类名,而是使用Sass的column混合器。

@include column($sidebar-columns);

还要注意$sidebar-columns变量。多亏了Sass,你现在可以通过变量来控制你的布局,多么强大啊。仅仅修改几个Sass文件顶部的变量,就可以快速地构建不同列、不同列间隔和不同边栏大小的原型。如果想在传统的CSS网格框架中做这件事情,你只能自己去计算这些东西,然后在你的HTML标签上修改类名。

这里我们就不展开Blueprint网格布局了,留待第6章直接使用。接下来,通过构建真实的Compass项目来进一步了解Compass的表格辅助器。

1.5.3 通过表格辅助器为表格添加更专业的斑马条纹样式

继续我们对Compass特性的探索,来看看它的表格辅助器。表格辅助器由一系列Sass混合器构成,它使表格样式编写更轻松容易,如代码清单1-18所示。

代码清单1-18 Compass表格辅助器

@import "compass/reset"
@import "compass/utilities/tables";
table {
  $table-color: #666;
  @include table-scaffolding;
  @include inner-table-borders(1px, darken($table-color, 40%)); @include outer-table-borders(2px);
  @include alternating-rows-and-columns($table-color,
                       adjust-hue($table-color, -120deg), #222222); }

我们一行行来看。首先通过@import引入表格辅助器,这样就有了4个可以使用的混合器。table-scaffolding混合类提供了最基本的样式修饰,用于已经过CSS重置处理的thtd元素,其中包括我们常用的一些修饰,比如说数字列会有一个右对齐。我们看看这个混合器的源码,如代码清单1-19所示。

代码清单1-19 表格辅助器中的混合器

@mixin table-scaffolding {
  th {
    text-align: center;
    font-weight: bold; }
  td,
  th {
    padding: 2px;
    &.numeric {
         text-align: right; } } }

inner-table-bordersouter-table-borders混合器正如其名,用于给表格以及表格内的单元格添加边框。

最后,alternating-rows-and-columns混合器提供了一种更简单的方式,来给你的HTML表格添加斑马条纹样式。你或许会问为什么不用:nth-child:even或者:odd等CSS伪类选择器呢?这是个好问题。其实,在底层Compass就是通过这种方式实现的。但是这个混合器除了样式上颜色的交错等修饰还会提供一些基于类名的脚本支持。我们看一下它的源码,如代码清单1-20所示。

代码清单1-20 按照行或列更改颜色的混合器

@mixin alternating-rows-and-columns(
               $even-row-color,
               $odd-row-color,
               $dark-intersection,
               $header-color: white,
               $footer-color: white) {
  th {
    background-color: $header-color;
    &.even, &:nth-child(2n) {
      background-color: $header-color - $dark-intersection; 
  } 
  tr.odd {
    td {
      background-color: $odd-row-color;
      &.even, &:nth-child(2n) {
        background-color: $odd-row-color - $dark-intersection; 
      }
    }
  } 
  tr.even {
    td {
      background-color: $even-row-color;
      &.even, &:nth-child(2n) {
         background-color: $even-row-color - $dark-intersection; 
      }
    }
  }
  tfoot {
    th, td {
      background-color: $footer-color;
      &.even, &:nth-child(2n) {
        background-color: $footer-color - $dark-intersection;
      }
    }
  }
}

注意,颜色值不仅仅是一个变量,它们之间还会用来进行一些计算,以便提供合适的对比来保证网页的可读性。下一章你将学到更多关于Sass处理变量和计算的知识。我们继续往下看,了解Compass是如何实现在写CSS时无需再写厂商前缀的。

1.5.4 CSS3属性无需再写厂商前缀

当CSS3的新属性被越来越多的浏览器新版本所采纳时,设计师们兴奋极了,因为他们可以用新的CSS属性实现以前需要非常愚蠢的样式技巧才能实现的任务。令人异常激动的是,现在用几行非常简单的CSS就能实现边框圆角,且不用在意随之而来的厂商前缀。厂商前缀就是浏览器在CSS特性前加的-webkit-moz等前缀,用于对试验中的CSS特性进行支持。举个最简单的例子,要给一个<div>元素设置5px的边框圆角,你必须要这么写CSS:

.rounded {
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
}

一般来说,使用Compass的CSS3模块中的边框圆角混合器可以免去你这部分的重复工作。首先在你的Sass文件中引入CSS3模块,然后引入混合器:


@import "compass/css3";
.rounded {
  @include border-radius(5px);
}

看一下生成的CSS:

.rounded {
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  -o-border-radius: 5px;
  -ms-border-radius: 5px;
  border-radius: 5px;
}

这样做,不仅避免了重复输入-webkit-moz,同时也支持了其他的一般常用的厂商命名空间,令你设计的网页可以在更多浏览器中保持良好设计。尽管这一点点重复看上去并不是那么恐怖,可如果你仅仅是想让第四个角是圆角呢?对此,火狐浏览器的开发者们并未就最好的实现方式与业界其他人士达成一致,而惯用的实现方式如下:

.rounded-one {
  -moz-border-radius-topleft: 5px;
  -webkit-border-top-left-radius: 5px;
}

这个地方,Compass有更好的实现。你可以通过border-corner-radius混合器来指定单个边框圆角:

.rounded-one {
  @include border-corner-radius(top, left, 5px);
}

生成的CSS如下,火狐的方式也包含在内:

.rounded-one {
  -moz-border-radius-topleft: 5px;
  -webkit-border-top-left-radius: 5px;
  -o-border-top-left-radius: 5px;
  -ms-border-top-left-radius: 5px;
  border-top-left-radius: 5px;
}

以上只是Compass中有关CSS3的冰山一角的一角的一角。第9章将更深入地接触所有能节省时间的特性。

1.6 小结

在这第1章,我们学习了CSS预处理的示例,并简单介绍了一下Sass的4个关键特性:变量、选择器嵌套、混合器和选择器继承。同时,我们也了解了一些Compass框架中Sass特性在真实世界程序中的应用,包括CSS重置、格式布局、表格样式修饰以及CSS3边框圆角。

下一章将进一步学习Sass的语法,包括颜色函数和脚本支持。当你对Sass掌握得更好一些时,我们将更深入地学习Compass。

目录