CSS3专业网页开发指南

978-7-115-34295-9
作者: 【英】Peter Gasston
译者: 李景媛吴晓嘉
编辑: 赵轩
分类: CSS/CSS3

图书目录:

详情

本书以现实世界中的例子为基础,向读者展示了如何将普通文字转换成效果惊人、细节丰富的网页,并且适用于任何浏览器。你可以掌握最新的尖端CSS的功能,如多栏式布局,边框和盒子的影响,以及新的颜色和不透明度设置。等等。

图书摘要

版权信息

书名:CSS3专业网页开发指南

本书由人民邮电出版社发行数字版。版权所有,侵权必究。

您购买的人民邮电出版社电子书仅供您个人使用,未经授权,不得以任何方式复制和传播本书内容。

我们愿意相信读者具有这样的良知和觉悟,与我们共同保护知识产权。

如果购买者有侵权行为,我们可能对该用户实施包括但不限于关闭该帐号等维权措施,并可能追究法律责任。


THE BOOK OF CSS3

Peter Gasston

Copyright © 2011

All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval system, without the prior written permission of the copyright owner and the publisher.

本书中文简体版由No Starch Press公司授权人民邮电出版社独家出版。

未经出版者书面许可,不得以任何方式复制或抄袭本书内容。

版权所有,侵权必究。


内容提要

本书是英国著名Web前端开发工程师Peter Gasston对CSS3高级技术的全面介绍。书中既有CSS3的发展历史、基本语法等入门知识介绍,也涵盖了媒体查询、选择器、伪类与伪元素、网页字体、文本排版、图形处理、动画、布局等CSS3前端开发必不可少的知识,还介绍了CSS3的未来发展方向。全书共分为17章,作者在每一章的讲解中都结合了大量的实例,同时也不忘介绍每一项技术的发展背景和适用场景,让读者对CSS3技术的应用真正做到融会贯通。


献给我的妻子,Ana,感谢她的耐心与支持


CSS3长期以来就一直是业内人士热议的话题。早在2006年,我创办了CSS3.info网站,Peter也加入进来。他撰写了一些文章,这些文章介绍了CSS标准的发展,还有CSS3在各种浏览器中呈现效果的真实示例。尽管是我创办了这个网站,但Peter一直以来都是最多产的作者,所以毫无疑问,我写出了序言,他则写出了这本书。

CSS3最终成为了主流。随着浏览器新时代的到来(诸如Firefox 4、Google Chrome和Internet Explorer 9等浏览器出现),网页设计社区终于获得了之前一直期待的那种能力和灵活性。我们现在可以管理媒体查询让网页适应不同的浏览器,也能够拥有更加智能的背景图片,还能够以一种较为从容的方式去处理字体。

如果你打算使用CSS3,这本书将会是你所能找到的最切合实际的指南。它会告诉你哪些行得通哪些行不通,同时还不忘给你一些提醒。Peter甚至还对过渡(transitions)与变换(transformations)是如何工作的给出了清楚的解释。这是非常了不起的!当你阅读到那些章节的时候自己也将深深地体会到matrix函数并不适用所有的用户。幸好,在你利用CSS3其他更易理解的函数时,并不是非得使用这些东西。

不止如此:CSS3也是一种不断扩展的标准,它承诺帮助网页开发人员实现伟大的目标。就我个人而言,我非常好奇它将会把我们引向何方。但是,若要发掘CSS3中的珍宝,现在这本书已经完全足够了。

Joost de Valk

Yoast.com的CEO和创始人


不论是我网上发表的文章还是已付印的作品,这本书都算得上是我这五年来对CSS3写作的顶峰。浏览器和CSS的景观在短时间内已经发生了很大的改变,直到今天也在持续不断地发生着变化,它们带来的新特性和新实现已经让人有点儿跟不上步伐了。CSS规范是用(通常是浓厚的)技术化语言撰写的,它的目的是供实现的人阅读而不是供最终用户使用。而我打算写的这本书,正是为了在CSS3规范与网页开发人员的鸿沟之间搭起一座桥梁。

在这本书前面的一些章节中,我写的是关于CSS属性的内容,因为它们都已经有良好的实现,并且每天都会被用到。在本书写作的早期过程,我还可以通过实验、通过先驱者以及早期使用者的工作和学习到许多东西。但是到了最后几章,我就不得不依赖CSS3规范的说明,才能够向大家解释未来的属性将会是什么样子的。我希望那些章节的错误能少一些,如果其中有任何错误,我承认都是由于我自己理解有误所致。

除了CSS3规范本身以外,还有一份无价的资源是Mozilla开发人员网络(Mozilla Developer Network,https://developer.mozilla.org/),其中有许多无与伦比的有关网页的文章——不仅仅关于CSS,而更让人出乎意料的是,这些文章全部是由志愿者所撰写的。本书许多代码示例所使用的文本都是从公共领域的书籍获取的,可以在此处获得:http://www.gutenberg.org/。本书的所有非原创图片在相关的章节中均已说明出处。

这本书也不可能少得了No Starch出版社团队的指导,特别是Serena Yang和我的编辑Keith Fancher,他们让我的写作变得更加清晰,也帮助我从一名博客写手转变成为一名书籍作者。我也要感谢Joost de Valk,他不仅仅充当我的技术编辑,还要感谢他 5 年前创建的http://www.css3.info网站,让我第一次有机会去撰写关于CSS3的文章。

我也要感谢我在Preloaded和Poke的同事给予的支持和鼓励,感谢在多次伦敦网页社区聚会上遇到的每个人,感谢我的妈妈教给我努力工作的价值,感谢我的爸爸大约在30年前买给我的第一台电脑——我答应过有一天我会报答他的,真心希望这本书多少有助于此。


首先要说说本书设定的目标读者:你应该是一个若干年来一直在手动编写HTML和CSS的网页专业人士;你应该习惯于创建复杂的布局,并且不仅知道div与span的区别,还要能够区分bold和strong的用法;你应该已经读过一点关于CSS3的东西,甚至还体验过它的一些更有装饰性的特性,比如圆角效果,但是对于这些基础的东西,你还希望有更加深入的理解。

本书可以帮助你利用所掌握的CSS2.1的精彩知识,将学习CSS3变得更加容易。我不会解释CSS的基础原理(除了偶尔的提醒之外),因为我假设你已经了解这些内容了。我也不会用一步接一步的演示和你讲解如何使用CSS去制作一个列表式的导航或者是一个图片库,因为我假定你可以把本书中的示例应用到你自己想要构建的任何事物中。

我写这本书的目的是为了向你介绍现在我们可以使用CSS3去做些什么,在未来能够利用它去实现什么。我要把CSS3规范那浓厚的技术语言转化为直白实用的话语。

简而言之,我要为你的工具箱添加一些新的工具,让你用它们做出非常酷的东西。

CSS可以被用在许多类型的媒体上,几乎所有能够显示HTML或XML的设备也同样能够按CSS规则去显示,即便有时候它们只能以有限的形式来显示。CSS3有两个模块专用于分页的媒体,例如PDF或者印刷材料,并且也支持盲文、手持式移动设备(例如,无线电话而不是智能手机)、电传打字机和电视。这种可能性的范围和幅度是如此广阔,所以我根本无法在这本书中全部涉及。

这本书所关注的是用于电脑屏幕上的CSS。所有的演示都是为了最常见的桌面浏览器所编写的(并且在上面进行了测试),也为桌面用户和笔记本电脑的用户进行了优化。对本书的许多新特性来说,如果你要为其他设备进行开发,它们仍然可以起作用——特别是智能手机和平板电脑——但我无法保证或确信所有东西都和书中的例子中所显示的一模一样。

我是在一台运行Ubuntu 10.04的电脑上(安装了Firefox、Chrome和Opera)撰写了这本书的大部分内容,因此也包括绝大多数的演示和例子。其他的一些内容则是在一台安装了Safari的MacBook Pro上撰写的。书中Internet Explorer的测试是在Windows 7系统上进行的(所有我使用的浏览器的精确版本可以在附录A的介绍中找到)。

纵览本书,我主要提及的是Firefox和WebKit。你应该可以敏锐地洞察到Firefox是一种浏览器的类型,而WebKit则是一种布局引擎类型,也想知道我为什么不提及Firefox所使用的Gecko布局引擎,或者提及任何基于WebKit的浏览器的名字。

原因其实很简单:毫无疑问,Firefox是一种出类拔萃的基于Gecko的浏览器,而Chrome和Safari哪一个能代表WebKit浏览器的卓越功能却仍存争论。为了节省篇幅,我会说“WebKit”而不会说“Chrome和Safari”。除非某种特定的特性或语法只出现在某一种类型的WebKit浏览器上的时候——例如Safari中的硬件加速3D变换——这种情况下,我就会使用上述浏览器的名称。

本书的结尾部分有两章附录,包含了各个章节所讨论内容之外的更多的信息。第一个附录提供了一份快速参考指南,介绍本书所包含的特性在各种不同版本的浏览器上的实现;而第二个附录则列出了在线资源、有用的工具和有趣演示。

本书的配套网站是http://www.thebookofcss3.com/,我在网站上保存了这两章附录的更新版本以及本书使用的所有例子和演示。但愿我不要犯下任何错误,但那是几乎不可能的,所以我也会在网站放上完整的勘误列表。

除了本书的配套网站之外,我会在自己的博客——Broken Links(http://www.broken-links.com)上撰写更多关于CSS3(以及其他的新兴网页技术)的文章。你可以进行评论或通过这两个网站与我联系。


在第一个章节中,为了说明本书所使用的代码约定,我会引入一个新的CSS3属性。但是在此之前,我要先对CSS3的历史做一番说明。很明显,使用CSS3并不需要了解它的历史,但我觉得,让读者对CSS当前状态的来龙去脉能够有所了解也是非常重要的。

CSS3是一个处于变化之中的规范。该规范的某些部分通常被认为已经稳定下来了,所以它们在现代浏览器中也得到了良好的实现。但是其他有一些部分常常被认为还是实验性质的,所以浏览器对这部分规范也只是有不同程度的实现。CSS3还有一部分内容仍然停留在理论建议阶段,而这一部分则根本没有被浏览器实现。此外,还有一些浏览器创建了自己的CSS属性,这些属性并不属于任何的CSS3规范,也许永远都不会被纳入规范当中。

这也就意味着,如果能了解标准化的过程是如何发生的、了解浏览器对每一个新属性的实现程度,对于我们现在和以后在自己的代码中去运用CSS3是至关重要的。

首先,我要谈谈CSS3究竟是什么、不是什么,还有它究竟有怎样的形式。WC3对CSS3所采取的方法和CSS2是截然不同的,所以,这一章对CSS3的概述应该有助于你理解什么时候可以使用CSS3、如何使用CSS3以及为什么它在不同浏览器上的实现有如此大的差异。

当前所使用的CSS版本是CSS2.1,这是CSS2规范的修订版,最初发布于1997年。尽管从那时起,该规范就在不断地发展并接受评审,但是当许多人听到CSS2实际上并没有成为W3C的“官方”推荐时,仍然会感到惊讶(马上我就要谈到这一推荐过程)。更出人意料的是,2009年发布的Internet Explorer 8(IE8),居然宣称它是第一款完全支持整个CSS2.1规范的浏览器。

在过去的这几年,人们对CSS的谈论一直围绕着它的新版本CSS3而展开。虽然我说这是“新的”版本,但实际上,W3C对CSS3的工作从1998年就开始了,而那一年正是CSS2发布之后的一年。在CSS2发布之后,CSS2的浏览器实现仍旧参差不一,非常令人沮丧。所以W3C决定中断所有CSS新版本的工作,反过头来致力于CSS2.1的发展,至此,CSS的标准化之路才在现实世界中得以践行。直到2005年,所有的CSS3模块才被移回到草案状态,而对它的编辑与评审过程也再一次从头开始。

多年以来,Internet Explorer一直占据了不断扩张的Internet用户市场,但它并没有显露出实现CSS3的迹象。过去的这几年,新出现的各种全新的浏览器为了争夺用户而展开竞争,过多的选择也导致了一场浏览器特性的军备竞赛,而这场军备竞赛的一大受惠者,就是CSS3。每个浏览器都要为开发人员和用户提供最新的网页技术,同时,由于CSS3规范大部分已经完成了编写,对它的实现甚至是新特性的添加都已经完全没有了障碍。

所以,对今天的我们来说,已经可以使用CSS3规范进行有效的开发,大量的浏览器也致力于实现这一规范,而具有共同利益的开发者们也已经使用CSS3去构建网页,对它进行学习,写下了关于它的种种文章。这是一种健康发展的态势,也是我们在几年以前完全无法预见到的。

要成为这个世界上所有基于标记的文档的默认样式化语言,可谓是一项艰巨的任务,W3C也意识到这一目标需要花上许多年才能够实现。同时,W3C成员也逐渐意识到,当他们对一些更加深奥难懂的特性进行考虑和争辩时,不能够阻挡一些有明显需求的特性加入。所以,他们决定把CSS3分割为各个模块,这样每个模块就可以由不同的作者以不同的步调进行处理,其实现和推荐的过程(我马上会谈到)就可以错开进行。

这就是为什么我们现在拥有的是CSS3的基本用户界面模块、选择器级别3、媒体查询,等等,而不是一份单独的、完整的CSS3规范文档。有部分模块是CSS2.1的修正版,有一部分则是全新创建的,但是它们全部都打着CSS3的旗号。

会令我生气(我是一个随和的人)的少数几件事情中,其中一件事情是,我在许多博客上会听到人们抱怨:“我想要使用CSS3,但要等到它准备好还要好几年呢。”这种说法是毫无意义的,CSS3的一些模块在所有现代浏览器上都已经有了非常稳定的实现,而更多的模块距离实现它们的黄金时间可能不过就是几个月罢了。如果要等到所有这些模块在现有的每种浏览器上都能百分之百地实现,不得不等上很长一段时间。

但 CSS3 就在这里,其中有一些模块现在就可以使用了——我们仅仅需要考虑如何使用就行了。

当我在这本书中前行,讨论每一种不同模块时,也会提到模块的状态。这种状态是由W3C设置的,它表示模块在推荐过程中的进展情况,但是要注意,该状态未必表示一个模块在所有浏览器中的实现程度。

当一份提议文档首次被接受为 CSS 的组成部分时,它的状态会被指定为工作草案(Working Draft)。这种状态意味着该文档已经被发布,并且正准备由社区进行评审——这种情况下,社区指的就是浏览器制造者、工作组和其他利益相关团体。一份文档也许会保持在工作草案状态很长一段时间并历经多次修订,而且并非所有的文档都能够通过这一状态等级,一份文档也可能会多次返回到该状态。

在文档可以从工作草案发展到一下阶段之前,它的状态会被修改为最终征求意见稿(Last Call)。这意味着一份文档的审核周期即将结束,通常也表明该文档已经准备好发展到下一级别。

接下来的这一级别称为候选推荐标准(Candidate Recommendation),意味着W3C已经确认该文档具有存在的意义,并且最新的评审也没有发现什么重大的问题,而所有的技术需求均已被满足。此时,浏览器的制造者也许就可以开始实现文档中的属性,收集现实世界的反馈。

当两个或更多的浏览器以相同的方式实现了这些属性,并且也没有暴露出严重的技术问题,一份文档就可以发展到提案推荐标准(Proposed Recommendation)。该状态意味着该提案现在已经成熟并且可以被实现,只需等待由W3C顾问委员会(W3C Advisory Committee)批准通过。当这一签注被同意之后,该提案就成为了一个推荐标准(Recommendation)。

对于前面简略谈及的内容,此处还要再重申一点,推荐过程与实现过程并不总是以相同的方式运作的。例如,在这本书的后面,我将会介绍一组模块,这组模块由WebKit团队在几年以前提出,其中包括了2D变换(2D Transformations,第12章介绍)。尽管该提案仍然处于工作草案状态,但这些属性在Firefox、Opera和基于WebKit的浏览器上已经有了很好的实现。

我在本章之前提到过的,即便是我们现在已经使用了很多年的CSS2.1也仍然没有达到完全推荐的状态。尽管CSS2.1几乎已经完成了,但仍然有一些语法和句式上的事情需要解决。很明显,这并不会阻碍浏览器充分实现它并转向CSS3。

因此,我在写这本书的时候,并没有严格根据模块推荐的状态进行叙述,而是按照特性实现的较为松散顺序进行讲解。前面的章节讨论的是在所有浏览器中都已经完全实现的特性(或者说截止本书发布为止);稍后的一些章节只涉及在某些浏览器上实现的特性,它们通常带有浏览器特定的前缀;而本书最后的章节则会谈及一些可能的、推测的或者有部分实现的属性。

当前在Internet上随处可见的一个流行词就是HTML5。当然,HTML5是一种真正的(也是激动人心的)新技术,它莫名地超越了技术出版物,来到了主流媒体上。几乎在你所去到的每一个地方,人们都在讨论它。然而,在这一旅途中,它的正确含义似乎已经消失了。

在我解释为什么这么说之前,应该先说明,媒体并不应当单独承担使HTML的真正含义变得模糊的责任。许多开发人员都热衷于做出绚丽的“HTML演示”,但如果仔细地看看这些演示(或者浏览一下它们的源代码),通常都会发现这些演示几乎都没有包含实际的HTML5新特性,而是使用了大量的CSS3技术。

尽管HTML5为网页带来了许多非常酷的新特性,但CSS3带给我们的才是真正充满想象力的视觉效果:旋转、缩放、二维和三维动画、动态和装饰性的文本效果、阴影、圆角和渐变填充效果,所有这些都是CSS3带给我们的(在这本书中我会展示如何使用这些特性)。

媒体所谈到的HTML5,实际上是结合了CSS3、SVG和JavaScript的标记语言的新修订版本,对于许多人(包括我自己在内)来说,更愿意把它称为Web栈(或者是开放Web栈,Open Web Stack)的一部分。

讲了那么多题外话和说明之后,我们现在来看看CSS3的实际内容。在整本书中,我在演示每条新规则和属性的时候,使用了某种语法上的约定。我不想简单地描述这一约定,我想如果我在介绍第一个CSS3新属性的时候,同时也解释一下这种约定,会让人觉得有趣许多。

我将介绍的这个属性就是box-sizing,它可以设定元素的大小应该如何计算。如你所知,一个元素的总宽度——不包括它的边距(margin)——通常从它规定(或继承)的width值计算而得到,再加上左右的padding(填充)和它的border-width(边框宽度)。我们用下面的代码来举例说明,这段代码对你来说可能已经非常熟悉了。

在这个例子中,div的总宽度是190px——即150px的width,加上20px的padding,再加上20px的border。当使用绝对值设置width的时候,这段代码不会有什么问题,也毫无争议,但是,如果在其中混入百分比值,这段代码就有点问题了:

现在,宽度会变得难以计算。这是因为只有先知道父元素的width值,才清楚它的15%究竟是多少,然后才能把相应的像素值加到宽度的计算中。这种情况下,计算很快就会变得非常复杂,所以我们很难恰到好处地管理基于百分比的布局。

此时,box-sizing属性就派上用场了。有了这个属性,我们可以设置用方框模型的哪一部分,即内容本身或者border(边框)去计算元素的宽度。在讲完为什么存在这样一个新属性之后,我将开始进行演示,查看它的语法。我在这个演示中所使用的约定也将会成为本书的标准。

在这个代码示例中,选择器用E表示。当然,在HTML中,E这个选择器是不存在的,我只是用它表示该位置可以使用任何的选择器。对于本节开头所使用的例子,E就代表了div元素。

接下来是属性本身:box-sizing。这个属性在所有主要浏览器上均已被实现。但在某些浏览器中,该属性需要使用浏览器特定的前缀:在Firefox中,要使用-moz-前缀,即变成-moz-box-sizing;而在WebKit浏览器中,使用的是-webkit-前缀,所以会变成-webkit-box-sizing。不过,使用所有这些不同的前缀并不会把代码弄得一团糟,我会根据CSS3规范只使用正确的属性名称,并在需要前缀的时候在文本中进行注释,就像我在这里做的一样(在下一节我会对这些浏览器前缀进行更多的解释)。

上述声明的值是单词keyword,同样的,这个值只是一个指示符,表示一系列可能的值。对于box-sizing,它所允许的值是border-box和content-box。

了解这些约定之后,如果用实际的值去代替,现实世界的应用程序中的一个新属性可能会是这样:

那么,这个属性有什么用呢?前面提过,box-sizing设置了元素计算宽度时要从哪个位置算起。默认值是content-box,也就是说对元素所设定的宽度会应用到该元素的内容上,而填充和边框值会照常添加上去。

如果把值设置为border-box,则意味着设定的width值是内容、填充和边框的总宽度——换句话说,是整个方框(没有边距)的宽度。为了举例说明,我们回到前面的示例代码中,然后添加该属性:

现在150px的宽度包括了填充和边框。二者在内容两侧都占据了10px,所以div元素的内容计算宽度就是110px,即150px减去20px的填充和20px的边框。

在形象化地举例说明这两个值的差异之前,我要先提一下Firefox(关于它的-moz-box-sizing属性)。Firefox额外有一个允许使用的值是其他浏览器所不具备的,就是:padding-box。如果使用这个值,计算元素宽度时会对它的填充和内容进行计算,而不包括元素的边框。下面是一个例子:

在这段代码中,150px的宽度包括了填充,所以内容本身的宽度是130px。在图1-1中可以看到这几个值在Firefox渲染的时候出现的差异。

从左到右依次看看这几个例子:第一个div的box-sizing设置为默认的content-box值,所以设定宽度150px就是内容的宽度,边框和填充的宽度会再添加到内容上;在第二个例子中,box-sizing的值是border-box,意味着150px的宽度已经包含了边框和填充,这样内容的宽度就是110px;最后,右侧的div使用了Firefox自己的-moz-box-sizing属性,所设定的值是padding-box,所以150px包括了内容和填充,但不包括边框,这样内容宽度就是130px。

请注意,在所有这些例子中,尽管我只讨论了width属性,但是同样的规则也可以应用到元素的height属性上(你也许会注意到进入“怪异”模式(“quirks”mode)的浏览器使用处理方式也是完全一样的)。

图1-1  box-sizing属性使用的不同值的效果

注意

 如果你是较“年轻”的开发人员,也许想不起“怪异”模式了。这是一个模仿Internet Explorer 5.5网页布局的错误方法的系统,可以在Wikipedia上了解到关于它的更多信息(http://en.wikipedia.org/wiki/Quirks_mode)。

在整本书中,我在几个例子中使用了box-sizing属性,所以如果其效果(以及它的好处)现在还无法立即显现,相信随着你对剩余章节的阅读,对它的感受应该会越来越深刻。

在上一节,我简略地讨论过在box-sizing属性上使用浏览器特定的前缀。由于CSS3仍然处于变化和修订之中,在本书的剩余部分我也会多次提到这一情况,所以,我要先花一些时间更详细地谈谈这些内容。

当一个模块仍然处于活跃评审状态时(多少就像CSS3自身一样),许多内容都有可能发生改变,属性的语法也许会被修订,或者属性也可能会被完全抛弃。有时,甚至是草案本身所采用的措辞都可能会有点儿含糊不清,所以人们可以进行开放的解释。

与此同时,浏览器却需要实现这些特性,这样我们才能够看到这些特性在实际中是如何发挥作用的。但如果两个单独的浏览器实现了同一个属性,但在解释该属性的时候稍微有点差异,这时麻烦就出现了:你的代码将会有不同的展示,也许在每个浏览器中都是完全不同的。为了防止这种情况发生,每种不同的浏览器引擎都会在实验性的属性前面加上一个简短的代码作为前缀。我们假设一个名为monkeys的属性(我一直想要一个monkeys属性),它是规范中一个全新的属性,并且所有的浏览器都决定实现它,看看它如何发挥作用。这种情况下,就必须使用下面的代码:


这种重复的数量似乎有些多余,但这种重复对我们自己来说却是有好处的。你最不愿意见到的事情肯定是所有浏览器对monkeys属性的实现都是不相同的,从而导致了混乱的发生(我在第11章讨论渐变的时候,你将会看到前缀优点的大量例子)。

通常,人们会建议在使用带前缀的、实验性的CSS属性的时候,也应该在结尾处添加无前缀的属性:

这种理论是为了让代码能够适用未来,这样当一个属性在各种浏览器中得到完全实现时,就不需要回过头来把该属性添加到样式表中。我过去常常支持人们使用这种技术,但现在我的态度也不是那么明确了。我想,如果不只一个浏览器已经以兼容的方式实现了该属性,这种适用未来的技术也还是不错的,因为这通常都表明在规范中这个属性已经稳定下来了。不过,如果规范仍然处于评审之中,它的语法就很可能会发生改变。当浏览器在实际中实现了更新的语法之后,添加无前缀的属性就可能会引起问题;或者,它甚至根本就不会起作用。

本书的一些属性——比如第8章的background-size就只实现了一半,也就是说它们在某些浏览器上还需要使用前缀,但在其他一些浏览器上则是无前缀的。这种情况下,很明显我们就需要把两种声明方式混合起来使用。如果要使用第11章的那些属性——它们是不成熟的,也仍然处于开放评审阶段,离最终结果仍然遥远,这种情况下我们最好不要马上就使用这种适用未来的方法。

对于这本书,这一切就是我们开始之前所需的全部内容了。当然,除此之外你还要具备好奇的天性。对于CSS3,我会涉及到许许多多的内容,所以讲解的步伐会相当快,但每一章应该都可以为你提供构建自己的测试、演示和网站所需的知识,让你能够享用CSS3所提供的灵活性和丰富特性。

我们先来看一个最简单的——却也可能是最具颠覆性(我指的是好的那一方面)的新特性:媒体查询(Media Queries)。


当万维网只能通过台式机或笔记本电脑浏览器去访问的时候,编写CSS是相当简单的。尽管那时也需要考虑跨浏览器和跨平台的问题,但至少我们能够合理地推断所有人在访问网站时,使用的设备从根本上看都是类似的。然而,在过去的这些年,我们看到了iPhone或iPad这样的设备在数量上急剧增加,所以,人们浏览网站使用的可能是宽屏桌面显示器或者狭窄的掌上屏幕,如果还是把内容以同样的方式呈现给每个人,实在不合乎情理。

长期以来,在CSS中有一种方法可以为不同的媒体类型提供不同的样式,这种方法使用的是link元素的media属性:

但是,如果屏幕尺寸有可能在3.5英寸到32英寸之间时,使用这种方式如同运用钝刀一般。对于这个问题,CSS3通过媒体查询模块(Media Queries Module,http://www.w3.org/TR/css3-mediaqueries/)提供了解决方案。媒体查询提供一种查询语法去扩展媒体类型,这种查询语法可以更加具体地为用户的设备提供样式。虽然媒体查询如此强大,但它在整个CSS3规范中实际上也只是众多最具革命性的特性之一。媒体查询可以给你一种自由,让网站真正地与设备无关,不管用户如何访问网站,都为他们提供最佳的合适体验。

媒体查询模块处于候选推荐标准状态,所以可以认为它已经准备好进行实现了。该模块在Firefox、WebKit和Opera上已经得到良好的实现,在Internet Explorer上要从第9版之后才能得到实现。

为了迅速展示媒体查询的能力和灵活性,我要使用一个例子,演示网站如何为移动浏览器进行优化,并且无需进行大量额外开发。

人们在移动设备上访问网站的时候很可能颇费周折:文本也许显示得太小,如果放大的话,又意味着需要大量的滚动才能找到导航元素;那些导航元素可能还包含了下拉的功能,手指需要悬停在上面才能触发它,这可是移动设备上通常并不存在的动作;大图片在数据连接比较弱时可能需要花费大量的时间去下载,耗费了每月的大部分带宽限额。一些网站打算为此提供方便移动访问的版本,但通常却需要大量的开发,必须建立一个子域,使用不同于父站点的样式表和HTML模板,图片也不得不重新调整大小以更好地适应小的屏幕,另外还需要创建脚本,检测用户是否使用了移动浏览器,然后重定向到相应的移动站点上。使用这种方法的话,可能会导致以下问题:脚本必须始终跟上所有移动浏览器的版本,为了保持移动和桌面版本的同步,通常还需要大量重复的维护工作。

媒体查询解决了许多问题。首先,它们会基于设备的属性来检测设备,这样就不需要使用浏览器探测脚本,之后允许直接安装设备的功能去设定目标样式表。所以,如果检测到用户使用小屏幕的设备,CSS规则就会调整以适应该屏幕尺寸,从屏幕上去掉无关元素,提供更小的图片,让文本变得更加清晰。

为了举例,不妨看看dConstruct 2010年会议的网站(http://2010.dconstruct.org/),如图2-1所示。

当我们在桌面浏览器中查看网站的时候,演讲者的网站推荐大图和文本会一列一列呈水平排列。通过媒体查询的力量,在比较狭窄的浏览器中(就像iPhone这样的智能手机所使用的浏览器)浏览这个网站时——演讲者的图片会被去掉,而指向演讲者页面的链接会更加突出,页面上所有的文本会移到单独的一列中,这样的布局对向下滚动的操作来说就非常理想了。

当然,这个网页绝不仅仅只在桌面和智能手机这两种设备上使用。事实上,我们需要致力于为所有设备提供网站优化,所以我强烈建议你读读Ethan Marcotte的文章,“响应式网页设计”(Responsive Web Design,http://www.alistapart.com/articles/responsive-web-design/),这篇文章对网页设计的新模式提供了非常好的介绍。

图2-1 在桌面浏览器(左)和移动浏览器(右)中查看dConstruct网站

如果想看看其他人是如何利用媒体查询的,这里有一个很好的在线图库,位于http://www.mediaqueri.es/,其中展现了一些可以实现的更出色的例子。

媒体查询设置了一个参数(或者一系列的参数),如果设备在查看页面的时候具有与该参数匹配的属性,就会显示与之关联的样式规则。我们可以通过三种方式去使用媒体查询,它们是和我们把CSS应用到文档的不同方式相匹配的。第一种是使用link元素去调用一个外部样式表:

第二种是使用@import指令调用外部的样式表:

第三种是在一个嵌入的style元素中或在样式表本身利用扩展的@media规则使用媒体查询:

这种方法就是我在本章接下来要使用的,因为使用这种方法可以更加清晰地进行演示。至于实际要使用哪一种方法,很大程度上取决于自己的喜好和现有样式表的结构。

现在我已经介绍了媒体查询的声明方式,我们再来探索一下它的语法。你对media属性应该已经比较熟悉了——它声明了样式要应用的媒体类型,就像HTML的link标签一样:

和当前的语法一样,我们可以使用逗号隔开的列表去选择多种媒体类型。

@media规则的第一个新属性是logic。可选的关键字可以是值only或not:

如果要对不支持该语法的浏览器隐藏规则,可以使用only值;对支持该语法的浏览器而言,only可以被有效地忽略。not值用于否定媒体查询,如果浏览器不满足设置的参数,就可以使用not来应用这些样式。

接下来的属性是expression,它是主要选择所发生的地方。可以使用and操作符去声明expression,并用它去设置媒体类型以外的参数。这些参数被称为媒体特征(Media Features),它们对媒体查询的作用是非常关键的。既然这样,我们还是详细地探讨一下。

媒体特征是与显示网页的设备有关的信息,它包括了设备的大小、分辨率等。这些信息被用于评估一条expression,评估的结果决定了哪些样式规则会被应用。例如,expression可以是“只在屏幕宽度超过480像素的设备上应用这些样式”或者“只在可以水平改变方向的设备上应用”。

在媒体查询中,需要为大多数的媒体特征表达式提供一个值:

在构造我刚刚提到的示例表达式的时候就需要这个值。不过在某些情况下,该值可以被忽略,只对媒体特征本身进行检测:

随着我进一步讨论媒体特征,解释这些值在什么时候是需要的、什么时候是可选的,这些表达式将会变得更加清晰。

了解完语法,我们来认识一些更加突出的媒体特征。接下来我要介绍的这些媒体特征最适合用于访问网页的彩色显示屏,也是最有可能在每天的工作中都要用到的。另外我们还可以使用其他的媒体特征,但它们更可能被用于电视或固定格栅终端这样的替代设备。

width媒体特征描述了特定媒体类型的渲染视区(viewport)的宽度,实际上,对于桌面操作系统来说,通常就是浏览器的当前宽度(包括滚动条)。其基本语法需要一个长度值:

在这种情况下,这些规则只会应用到宽度被精确设置为600px的浏览器上,这样可能太过具体了。不过,width也可以接受两个前缀max-和min-中的一个,可以对最小或最大的宽度进行检测:

上面的第一个查询会在宽度不超过480px的浏览器上应用规则,而第二个查询会把规则应用到宽度至少在640px的浏览器上。

我们来看一个实际的例子。这里,我为较宽的浏览器窗口提供装饰性的标题,充分利用了浏览器窗口的尺寸:

该媒体查询会对宽度至少为400px的浏览器窗口进行检测,如果符合条件,就把背景图片应用到h1元素上。也就是说,如果我的浏览器窗口至少有400px宽,就可以看到这张图片;如果我重新对窗口进行调整,使窗口变得更窄,就只会显示文本的标题。该示例如图2-2所示。

图2-2 使用width媒体查询应用不同的样式规则

height媒体特征所起的作用是相同的,只是它是以浏览器的高度而不是宽度为目标。其语法和width一致,也允许使用max-和min-前缀:

不过,由于垂直滚动这样的操作方式更为流行,height的使用频率远远不如width。

device-width媒体特征的功能也是类似的,但它描述的是渲染页面的设备宽度。在处理网页的时候,设备宽度是指显示该页面的屏幕宽度,而不是浏览器窗口的宽度。就像width和height,device-width的基本语法需要一个长度值,同样也能够以相同的方式添加前缀:

在为移动设备(这样的设备具有更小的显示区域)进行设计的时候,device-width是最有用的。使用这种特征,可以让设计满足较小的设备,不必创建专门为移动网页而设计的全新版网站。

例如,为了让内容在两种不同的设备上显示, 我会对它们进行优化。默认情况下,我会使用两个内容框,让它们在水平紧靠着放在一起。相反,对于较小的设备(在这个例子中我使用的是iPhone),方框将不会浮动,它们会按顺序从上到下摆放,从而更好地利用较窄的设备。以下是代码:

默认情况下,我使用一个500px的容器元素,里面有两个浮动的div元素,宽度为235px,水平边距为15px。之后,我创建了一个媒体查询(使用only操作符对较老的浏览器进行隐藏),该查询只会应用到最大宽度为320px的设备上(iPhone的默认宽度)。这条查询设置了应用的规则,去掉width和margin属性的确切值,防止方框浮动起来。我们可以在图2-3中看到结果,网页的内容对目标设备进行了更加恰当的格式调整,在可读性上也不会有任何损失,不需要使用特别的“移动版本”。

图2-3 device-width媒体查询在桌面(左)和iPhone(右)上以不同的方式显示内容

注意

 OS(iPhone、iPad,等等)和Android设备会通过四个屏幕侧边中较短的一对去测量device-width。也就是说,给定尺寸为320×480的设备,不管是以纵向还是横向模式去查看,device-width都会是320px。

device-width媒体特征同样具有对应的device-height,其操作如同height对应于width。同样地,device-height也使用了类似的语法,还有max-和min-前缀:

和height非常类似,对device-height的使用也比device-width少一些,因为垂直滚动比水平滚动也要容易一些。

到现在为止,在这些例子中我倾向于先创建一个为较大的浏览器或设备而优化的站点,再使用媒体查询为较小(移动的)的设备提供不同的样式。这种方法用来演示还是很不错,但在自己的网站中,实现的方式可能恰好相反。

我们在现实中之所以要这么做,是由于某些浏览器加载页面资源(比如样式表中包含的图片)的方法所致。一些媒体查询的早期采用者,先使用大的背景图片,之后在移动设备设置display:none,将图片隐藏起来。不过,尽管这些背景图片不会显示,但仍然可能被下载并存放在缓存中。这种方式增加了页面的加载时间,也可能会消耗带宽流量——对于没有无线连接的移动设备用户来说一点儿好处都没有。

所以,创建页面的更好方法是先为移动受众制作一个基本的样式表,然后再为桌面或平板用户制作一个带较大资源的样式表,最后使用像device-width这样的媒体查询来加载:

如上,采用这种方式把样式表分开以后,对于屏幕宽度小于480px的设备,将不会加载desktop.css,那些大资源也不会在后台下载。

这种方式对过去这几年出现的大部分浏览器都有很好的效果。相反,那些真正比较老的浏览器只会得到基本的样式表,这样对它们来说更好一些,因为它们可能无法应付本书剩余部分将会讲授的那些高级特性。

这种方法会出现的最大的例外就是Internet Explorer(要习惯这句话,因为你还会听到许多次)。不过IE9倒是支持媒体查询,只是之前的版本都不支持。为了解决这个问题,我们需要使用只有Internet Explorer能够识别的条件注释去加载这个桌面文件:

上面代码的简单含义是:“如果你所使用的Internet Explorer的版本低于第9版,就加载desktop.css文件。”虽然这样有点重复,但可以有效解决这个问题,并且让你用一种渐进的方式构建自己的网站。

如果对查看网页的设备的实际尺寸并不是太关心,但是要为水平方向(比如常见的网页浏览器)或垂直方向(比如电子书阅读器)两种网页浏览方式进行优化,需要使用的媒体特征是orientation。以下是它的语法:

它的value可以使用两个选项:landscape或者portrait。Landscape值会在浏览器宽度大于高度的时候被应用,而portrait值会在相反的情况下应用。尽管orientation肯定可以应用到桌面浏览器上,但其最大的用处还是处理用户可以轻易旋转的设备,就像新一代的智能手机和平板电脑。

例如,我们可以使用orientation,根据网页访问者的浏览器方向,水平或垂直地显示一个导航菜单。代码如下:

默认情况下,li元素的float值设置为left,这样可以让它们横跨页面叠放起来。如果以portrait方向查看同一个页面(要么重新调整浏览器,让它高于其宽度;要么在具有纵向模式的设备中查看页面)——浮动就会被去掉,相反,li元素会垂直地堆叠起来。可以在图2-4中看到其结果。

图2-4 在Android浏览器上的orientation媒体查询:landscape(左)和portrait(右)

因为对orientation特征来说只可能有两个值,所以如果使用其中一个值应用有差别的规则,另外一个就自然是相反的。在这个例子中,我只使用了portrait值,所以在默认情况下,所有在作用范围之外的规则都会应用到landscape方向上。

你也可以创建一些只有满足特定的宽度-高度比例才会应用的查询。要创建这样的查询,可以使用aspect-ratio特征检测浏览器的高宽比,或者使用device-aspect-ratio特征检测设备的高宽比。以下是这两种特征的语法:

其中,水平和垂直的值都是正整数,代表查看设备的屏幕宽度与高度(对应的)的比值,所以正方形的显示将会是1/1,而电影的宽屏显示则会是16/9。

我们通过高宽比进行选择的时候可能有许多地方需要注意。例如,某些设备制造商把宽屏定义为16:9,有一些是16:10,还有一些则是15:10。这样的变化意味着如果要应用针对“宽屏”的规则集,在选择的时候就必须把所有这些变化都作为参数包含进来。

一般而言,CSS像素单位(px)是指计算机屏幕上一个单独像素的大小——如果屏幕的分辨率是1024px×768px,我们把一个元素的宽度设置为1024px时,可以预期它在水平方向上将填满整个屏幕。不过,对于智能手机和移动设备来说情况并不总是这样。在它们的小屏幕上访问网站,通常需要放大显示,这样会导致屏幕像素大于CSS像素。例如,以100%的比例放大页面,意味着1个CSS像素会以4个设备像素(2×2)的大小在屏幕上显示。

对于可缩放的内容,比如文本和矢量图形,放大不会导致什么问题;但对于位图格式的图片,放大的时候可能会导致严重的失真。为了解决这个问题,许多设备目前使用了具有更高像素密度比的屏幕,能够以高分辨率显示而没有任何失真。例如iPhone 4,它的像素密度是2,意味着每个CSS像素会以4个设备像素显示在屏幕上(就像上一段的例子一样),能够以100%的比例放大而不会丢失任何细节。

媒体特征可以根据设备的像素密度去判断设备。该特征就是device-pixel-ratio,它在Mobile WebKit中的实现带有-webkit-前缀。

其中,number是一个小数,表示设备的像素密度。例如,三星Galaxy S的像素密度是1.5,如果要以类似的屏幕作为目标,可以使用:

和其他媒体特征一样,也可以检测最大和最小像素比:

这样的灵活性使我们为更高像素比的浏览器提供高分辨率的图片变得更加容易,正如这段代码:

第一条规则()意味着“标准”(或低分辨率)像素比设备上的浏览器将使用标准图片(image-lores.png);相反,像素比至少在1.5的设备则使用高分辨率的图片(image-hires.png)()。注意这里background-size属性()的使用,这个属性使用时应该用高分辨率的图片,以保证这些图片的显示不会大于要应用的元素(我会在第8章完整地介绍background-size)。

在Firefox Mobile浏览器(在写这本书时仍然是beta版)中应该也可以检测像素比,尽管其最大像素比和最小像素比的媒体特征在语法上有所不同:

可以用and操作符添加表达式,把多条查询链接在同一个媒体类型上:

这种语法在应用选定规则之前,先测试两个表达式是否匹配。例如,要测试16:9宽屏格式的小屏幕,可以创建如下查询:

也可以在多种媒体类型上设置不同的表达式:

这里每一条不同的表达式将会被用到每一种媒体类型上。例如,为所有横向设备和纵向投影设备设置一些规则:

当然,也可以创建上述语法的任何组合。

作为Firefox Mobile工作的一部分,Mozilla团队引入了许多专有的新媒体特征,其中有许多是Gecko(Firefox的渲染引擎)特有的,但也有一些被推荐给W3C作为正式的媒体特征。在以下地址可以看到所有这些内容:https://developer.mozilla.org/En/CSS/Media_queries#Mozilla-specific_media_features

其中,也许最令人感兴趣的是-moz-touch-enabled,它可以专门把规则应用到触摸屏幕设备上的元素,比如说,让按钮变得更大以适合手指(而不是尖笔或者鼠标)的操作。以下是它的语法:

对于某个设备来说,要么是可触摸的,那样的话它的值就是1,要么就是不可触摸的,其值就为0。这种情况下,就不需要声明一个值参数,可以只使用特征关键字,如上。

媒体查询的语法也许很简单,但它特别的强大。随着近年来移动网页的激增,设计人员和开发人员开始认识到他们有能力根据用户调整内容,不需要使用浏览器探测的老技术,也不需要从网站中分离出一个(完全不同的)移动版本。

媒体查询已经受到一些网页开发领军人物的认可和称赞,有关媒体查询作用的讨论也已遍及所有大型的网页会议。这种热情在很大程度上是由于克服小屏幕手持设备的网页浏览限制有着很大的需求,但是现在这种热情也可以说是被早期的iPad采用者的兴奋所驱动。

经过对媒体查询的深思熟虑和熟练使用之后,不管用户如何访问网页,你都可以为他们创建伸缩自如的网站。

WebKit

Firefox

Opera

IE

媒体查询

否(IE9有望支持)


相关图书

CSS选择器世界(第2版)
CSS选择器世界(第2版)
HTML+CSS+JavaScript完全自学教程
HTML+CSS+JavaScript完全自学教程
零基础入门学习Web开发(HTML5 & CSS3)
零基础入门学习Web开发(HTML5 & CSS3)
CSS新世界
CSS新世界
HTML CSS JavaScript入门经典 第3版
HTML CSS JavaScript入门经典 第3版
HTML+CSS+JavaScript网页制作 从入门到精通
HTML+CSS+JavaScript网页制作 从入门到精通

相关文章

相关课程