HTML5 和 CSS3 Web 演化入门指南(五)

原文:Beginning HTML5 and CSS3 The Web Evolved

协议:CC BY-NC-SA 4.0

十、改进网页排版

很长一段时间,网页排版是一个被忽视的领域。尽管文字技术的进步反馈到了 Adobe Photoshop 或 InDesign 等编辑软件中,但浏览器不得不处理一套非常基本且有限的文字技术。然而,随着 CSS3 的出现,这一切都在改变。在我们深入研究 CSS3 提供的制作字体的新工具之前,让我们先弄清楚“字体”的含义以及在网页排版中使用的各种术语。

字样和字体

我们来定义一下术语。

  • 字体:指由字体设计师创作的字体设计。乔治亚、Helvetica 和未来都是字体。可以在纸上创建字体,然后在字体设计应用中进行调整,或者在 Font Lab 等软件程序中创建。构成字体一部分的字母具有可以通过各种设置进行调整的特征。
  • 字体:字体可以打印字样。字体可以是金属的,也可以是数字的。在这一章中,我们将只讨论数字字体。

Jon Tan 写道字体不是字样,网页设计师不应该犯这样的错误。

解剖型

字体的解剖结构如图图 10-1 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-1。**解剖型

  • 基线:所有字符“坐”的线
  • 中间线:决定字体中非升序字符结束的线。
  • X 高度:基线到中线的距离。
  • 上升段:小楷字符延伸到字体中线以上的部分。在图 10-1 中,它是“h”的一部分,位于该单词中所有其他字母之上。
  • 下行线:小写字符延伸到字体基线以下的部分。在图 10-1 中,它是“p”的一部分,延伸到该单词中所有其他字母的下方。
  • 字形:字形指的是一种类型的单位。它可能是一个“ü”或一个普通的“a”。这些字形根据我们使用的字体有独特的风格。
  • 连字:两个或多个字形连在一起形成一个字形。在拉丁文字中不常见到(流行的拉丁连字是 ffl 和 FFI);它在印度语和 CJK 语中更常用。
  • 前导:这是指文本行之间的空间。我们在样式表中用line-height属性对此进行了设置。
  • 字母间距:指一个单词或一段文字中,字母之间的间距。我们可以用letter-spacing属性来控制它。
  • 字距调整:当我们调整两个特定字符之间的间距时,我们字距调整。根据定义,等宽字体在字符之间有固定的间距,不能进行字距调整。大多数字体都有由排版引擎自动应用的字距调整定义。我们后面会讲到如何控制字符间距。
  • 通用字体系列:这是一个专门用于网页排版的术语。当我们在网上设置我们的类型时,我们想要的类型可能不可用。在这种情况下,我们可以通过声明一个通用字体系列来指定我们希望页面呈现的字体类别。有五种通用字体系列:衬线字体(例如,Times)、无衬线字体(例如,Helvetica)、草书字体(例如,Zapf-Chancery)、幻想字体(例如,Western)和等宽字体(例如,Courier)。未能设置通用字体系列会导致浏览器选择自己的默认字体(根据浏览器和用户的定制而有所不同)来呈现我们的页面。
  • 对齐:文本相对于页面的设置。典型值包括左对齐、右对齐、居中或两端对齐。在网络上,对齐的文本容易产生大量的文本。稍后我们将会看到一些解决方案。
  • 寡妇和孤儿:在一列的顶部或底部悬空的短文本行。孤儿被留在底部,寡妇被留在顶部。

虽然有各种各样的方法来调整字体的一些特征,但是通过 CSS 来调整 web 字体的能力是最近才引入的。这里有一个 web type 的简史,可以帮助你理解它是如何开始的,以及我们下一步要去哪里。

网页类型简史

在 Web 的早期,样式表不是由网站的作者创建的,而是由用户创建的。作为用户,您可以指定一个通用样式表,其中包含您希望看到的字体类型,并且您访问的所有网站都将以您指定的样式呈现。这意味着您可以完全控制用于显示网页的字体。

这种情况在 1994 年 10 月左右发生了变化,当时提出样式表不是由用户设置,而是由服务于 HTML 页面的用户设置(这是一个相当彻底的变化!)这就提出了一个问题。如果用户没有样式表作者指定的字体会怎样?例如,如果你作为设计者指定了 Helvetica 新光的字体系列,如果用户的计算机上没有安装该字体,浏览器将如何呈现文本?

CSS 的原始作者霍肯·维姆·利和伯特·波斯考虑了这个问题,并提出了几个选项:

  • 从服务器上提供字体:没有普遍认可的字体格式(在早期,甚至 TrueType 或 OpenType 字体都不存在),并且在 90 年代带宽如此缓慢的情况下(还记得 96kbps 的调制解调器吗?)不可能及时下载字体文件来呈现页面。
  • 传递几个值并动态生成与所请求的字体相似的字形:这不是最佳选择,有时会导致难看的结果。
  • 作者按照偏好的顺序设置一个字体列表,希望其中一个可用:作者还可以设置一个默认的通用字体,如果作者选择的字体都不可用,浏览器将使用该字体从用户的计算机中找到合适的字体。

最后一个选项您可能很熟悉,因为它在 1996 年成为了一个标准。

微软还创建了一个可自由分发的字体堆栈,在屏幕上清晰可辨,并支持国际化,因此它可以用作 web 排版的基础。这导致了 Arial、Courier 和 Comic Sans 在各种操作系统中的扩散。

不幸的是,直到 2008 年才有更多的动作。与此同时,前端设计师试图通过图像替换、sIFR、Cufon 或 SVG 字体,创造性地解决网络排版的问题。在我们研究网络字体的现代奇迹之前,让我们先来看看这些选项。

维基百科的网页排版页面涵盖了各种网页排版格式的历史。

文本作为图像

呈现用户机器上不可用的字体的最常见方式是将其作为图形。这种技术有无数种变化,每一种都消除或增加了对这些图像使用方式的限制。以下是其中的一些。

法纳图像替换(FIR)

Farhner Image Replacement 是解决样式表中印刷限制的最早发明之一。FIR 以 Todd Farhner 命名,由 C. Z. Roberton 在 1999 年发明,并由 Doug Bowman 和 Jeffery Zeldman 推广,是使用 CSS 用图形替换文本的最流行的方式。有关浏览器支持的信息,请参见表 10-1 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这种方法的不利之处在于,它使文本对屏幕阅读器不可用,并且对默认关闭图像的用户不呈现任何内容(考虑到当时的带宽限制,这是一个很大的数字)。

转到[jsfiddle.net/nimbu/Q274j/](http://jsfiddle.net/nimbu/Q274j/)了解代码中表示的技术。

莱希/朗里奇法

Seamus Leahy 和 Stuart Langridge 独立地发现了一个可以帮助用户使用屏幕阅读器的解决方案。通过填充文本元素,该方法将文本推到元素的可视区域之外,使其对屏幕阅读器仍然可见,但对桌面用户隐藏。参见表 10-2 了解浏览器对此方法的支持。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不幸的是,关闭图像的用户无法看到文本。

转至[jsfiddle.net/nimbu/pnRb8/](http://jsfiddle.net/nimbu/pnRb8/)了解代码中表示的技术。

法尔克法

同时,Mike Rundle 提出了一个使用text-indent隐藏文本的解决方案。这意味着屏幕阅读器仍然可以访问文本,但是关闭图像的用户无法看到文本(表 10-3 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

转到[jsfiddle.net/nimbu/8ZMmT/](http://jsfiddle.net/nimbu/8ZMmT/)查看代码中显示的技术。

吉尔德/莱文法

Levin Alexander、Petr Stanicek(又名“Pixy”)和 Tom Gilder 发明了一种技术,适用于屏幕阅读器和禁用图像的用户。基本上,它利用一个空元素来应用背景图像,并呈现在文本之上。它带有一个很大的警告:图像不能是透明的。更多信息参见表 10-4 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

转到[jsfiddle.net/nimbu/Ra6p5/](http://jsfiddle.net/nimbu/Ra6p5/)查看代码中显示的技术。

JavaScript 图像替换(JIR)

Peter Paul Koch 采取了不同的方法,提供了一个 JavaScript 图像替换解决方案([www.quirksmode.org/dom/fir.html](http://www.quirksmode.org/dom/fir.html))。这种方法首先在进行图像替换之前通过 JavaScript 检测图像是否被禁用,从而解决了文本对屏幕阅读器或禁用图像的用户不可见的问题。Stewart Rosenberger ( [www.alistapart.com/articles/dynatext/](http://www.alistapart.com/articles/dynatext/)))将其扩展为使用 PHP 在服务器上自动生成图像。参见表 10-5 。

然而,所有这些技术都有一个缺点,即当字体大小改变或文本所占宽度改变时,不能缩放。他们不允许任何文本是流动的,而只适合预先确定的框。

进入 sIFR

转到[jsfiddle.net/nimbu/Q6FBQ/](http://jsfiddle.net/nimbu/Q6FBQ/)查看代码中显示的技术。

在 Mezzoblue ( [www.mezzoblue.com/tests/revised-image-replacement/](http://www.mezzoblue.com/tests/revised-image-replacement/))上可以找到图像替换解决方案的完整列表。

尼古拉斯·加拉格尔还在[nicolasgallagher.com/css-image-replacement-with-pseudo-elements/](http://nicolasgallagher.com/css-image-replacement-with-pseudo-elements/)写了一篇关于鲜为人知的纳什图像替换技术的文章。

SIF

2001 年,Mike Davidson 在 ESPN.com 首次大规模使用 Flash image replacement,为安装了 Flash 的用户提供嵌入 Flash 电影的自定义标题字体,为没有安装 Flash 的用户提供纯文本。2004 年,肖恩·因曼发明了一种更好的技术(被称为肖恩·因曼闪存替换;参见[www.mikeindustries.com/blog/archive/2004/08/sifr](http://www.mikeindustries.com/blog/archive/2004/08/sifr)),它处理普通的 HTML 并通过 JavaScript 添加了一个动态生成的 Flash 电影来代替普通文本标题。到 21 世纪初,Flash 几乎无处不在,这使得这项技术很容易落后。

2004 年末,迈克·戴维森和肖恩·因曼合力发布了一个更好的版本,名为“sIFR ”,它可以处理多行文本,不需要精确的尺寸,并在 Flash 电影中呈现出适合纯文本尺寸的字体布局。最大的缺点是,您必须使用不比用于呈现纯文本类型的字体更窄的类型,并且如果您调整了文本的大小(假设您单击了“text-size -> 200%”),文本不会调整大小。参见表 10-6 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 这些浏览器需要启用 JavaScript 并安装 Flash 6 或更高版本。

优惠券

Cufón 的目标是通过在现代浏览器中使用新的canvas元素和在 IE 中使用 VML 元素来取代 sIFR。Cufón 要求我们将想要使用的字体上传到他们的在线生成器,生成器会将它们转换成 Cufón 可以理解的格式。然后,我们需要将生成的文件包含在 Cufón 的 JavaScript 文件中,以我们的自定义字体呈现文本。

像其他图像替换解决方案一样,Cufón 现在允许我们选择被替换的文本。像 sIFR 一样,要替换的文本越多,渲染的时间就越长。

位于[github.com/sorccu/cufon/wiki/](https://github.com/sorccu/cufon/wiki/)的 Cufón Wiki 有更多详细信息。

SVG 字体

2001 年 10 月,SVG 1.1 工作草案发布了一个字体元素,允许用户用 SVG 语法指定字形。规范中概述的该元素的目的是

…允许在仅显示的环境中传送字形轮廓。网页附带的 SVG 字体必须仅在浏览和查看情况下受支持……

SVG 字体的一个关键价值是保证 SVG 用户代理的可用性。在某些情况下,SVG 字体可能是呈现某些文本的首选。在其他情况下,SVG 字体可能是备用字体,以防给定用户无法使用首选字体(可能是提示的系统字体)。

SVG 1.0 规范,[www.w3.org/TR/2001/REC-SVG-20010904/fonts.html](http://www.w3.org/TR/2001/REC-SVG-20010904/fonts.html)

这正是 SVG 字体最近变得突出的原因。iOS 设备不支持渲染开放字体的功能,但 Mobile Safari 和 Opera Mobile 可以渲染 SVG 字体。不幸的是,这意味着字体失去了提示,并且——取决于字体——在小屏幕上看起来更差。我们可以使用著名的@font-face 规则来包含 SVG 字体,稍后我们将对此进行研究。

SVG 字体有一些优点。我们可以在同一个文件中包含几种字体。这节省了网络请求,而网络请求是移动浏览器页面加载缓慢的主要原因。

不幸的是,Firefox 还不支持 SVG 字体,不像今天的其他主流浏览器([bugzilla.mozilla.org/show_bug.cgi?id=119490](https://bugzilla.mozilla.org/show_bug.cgi?id=119490))。这使得 SVG 成为字体格式战争中的外围玩家。

现在让我们来看看最近历史上的一个显著现象,它让我们能够平稳地过渡到在网站上使用网络字体:@font-face 的兴起。

@font-face

@font-face 是 CSS3 字体模块中的一个标准化规则,它最初是在 2002 年作为工作草案推出的。@font-face 允许我们声明字体在互联网上的位置以及它们的格式,这样它们就可以在我们的样式表中作为font-family属性的值使用。有趣的是,@font-face 已经在 CSS 规范中出现了一段时间,但没有被大多数浏览器实现。我们来看看它的演变。

网络资源

在没有定义网络字体的情况下,我们已经走了很远。 Web 字体简单地指所有可以通过在@font-face规则中声明来使用的字体。通常,所有这些字体都已针对 web 使用进行了优化;因此,它们具有较小的文件大小,并且在使用较小的字体大小时具有正确渲染的别名。

开始时

1996 年,当 CSS 级规范正在制定中时,Adobe 与 Bitstream、Microsoft 和其他公司一起提出了@font-face 提案,宣布了如下@font-face 规则:

@font-face { font-family: 'Graublau Web'; src: url('GraublauWeb.ttf') format('ttf'); }

由于对所有平台的字体格式没有明确的共识,W3C 没有推荐字体格式。这个规则是 CSS 2.1 的一部分。

这个特性也没有考虑到对下载字体的任何形式的限制,所以字体铸造厂开始担心它会被用于字体盗版。

微软与 Monotype Imaging 合作,提出了一个花园墙 DRM 解决方案,它使用了一种新的字体格式(EOT ),这种格式不能安装在任何计算机上,只能被浏览器(在这种情况下是 Internet Explorer)理解,以在页面上呈现字体。不幸的是,其他浏览器供应商不想采用这项技术。这意味着几乎没有商业字体可以通过@font-face 规则用作 web 字体,所以很少有开发者采用这个特性。这种假死状态一直持续到 2006 年。

@font-face 反击

2006 年,CSS 工作组决定采取行动,寻找一种单一的格式来终结图像替换技术。2007 年 10 月,Webkit 开始支持@font-face 规则链接 raw TrueType 和 OpenType 字体;Firefox 于 2008 年 10 月推出,Opera 于 2008 年 12 月推出。他们都没有认可微软首创的 EOT 格式。一种新的字体格式被认可,叫做 WOFF。它提供了字体数据的轻量级压缩,以及用于通知用户许可信息等的附加元数据。参见表 10-7 了解当前对各种格式的支持。

剖析字体语法:@font-face 声明

让我们花一分钟来理解@font-face 规则。这就是@font-face 在样式表中的声明方式:

@font-face {   font-family: bodytext;   src: url(ideal-sans-serif.woff) format("woff"),        url(basic-sans-serif.ttf) format("opentype"); }

在这个规则中,font-family 声明了我们实际使用时用来指代这个自定义字体的名称。例如,此规则中指定的字体可以按以下方式使用:

  p {     font: 12px/1.5 bodytext, sans-serif;   }

这将使用我们用名为“bodytext”的字体族指定的字体来呈现p元素中的所有文本

第二个属性src链接到我们想要使用的字体的实际 URL。

问题是并非所有的浏览器都理解所有的字体格式(见表 10-7 ),所以我们必须指定一个或多个这样的 URL 以及 format 函数来指示 URL 引用的格式。这个例子首先声明一个 WOFF 字体格式的 URL,然后声明一个 OpenType 的 URL。

我们也可以使用src中的local()函数来呈现一种字体,如果它在本地可用的话。虽然这是出于好意,但是如果本地字体损坏,将不会呈现任何文本。这可能是一个超出 web 开发人员控制的关键问题。因此,您应该避免使用本地字体,只从字体 URL 读取。

font-face规则中,我们也可以使用像font-weight: boldfont-style: italic这样的字体描述符。这些都是指示浏览器不要在必要时人为地为这些网页字体生成粗体或斜体。当这个font-face规则应用于一个标题时,就像这样

H2 { font: 16px/1.5 bodytext, sans-serif; font-weight: bold; }

浏览器被迫人为地生成更粗的字体。为了防止这种情况发生,我们只需要将我们的 web 字体描述为粗体,这样就可以按原样使用了。

@font-face {   font-family: bodytext;   src: url(ideal-sans-serif.woff) format("woff"),        url(basic-sans-serif.ttf) format("opentype");   font-weight: bold; }

这对我们的p选择器没有影响,但是防止我们的h2标题有一个合成的粗体字(这看起来比原样包含字体要糟糕得多)。

@font-face 的防弹语法

根据上一节的内容,您可能会认为编写一个适用于所有浏览器的@font-face 规则并不是什么难事。不幸的是,的确如此。我们需要确保浏览器只下载我们指定的几个资源中的一个,这样我们的页面才能快速加载。幸运的是,有一种语法可以做到这一点。Paul Irish 提出了第一个简单的通用解决方案,然后由 Richard Fink 完善,最后由 Ethan Dunham 完善。

@font-face { font-family: 'MyFontFamily'; src: url('myfont-webfont.eot'); /* IE9 Compat Modes */ src: url('myfont-webfont.eot?iefix') format('eot'), /* IE6-IE8 */ url('myfont-webfont.woff') format('woff'), /* Modern Browsers */ url('myfont-webfont.ttf')  format('truetype'), /* Safari, Android, iOS */ url('myfont-webfont.svg#svgFontName') format('svg'); /* Legacy iOS */ }

如果您担心生成这些格式的字体,不用担心。FontSquirrel 有一个@font-face 生成器(在[www.fontsquirrel.com/fontface/generator](http://www.fontsquirrel.com/fontface/generator)),可以自动将你上传的字体转换成所有支持的网络字体格式。首先确保您有权限将您的字体用作 web 字体。

下载 web 字体需要一些时间,这意味着用户需要等待才能看到使用您指定的字体的文本。这就产生了一个“无样式文本闪现”的问题,您将在接下来了解到这一点。

Paul Irish 关于防弹语法的帖子对这些选择都有详细的解释([paulirish.com/2009/bulletproof-font-face-implementation-syntax/](http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/))。

避免无样式文本的闪烁(FOUT)

下载 Web 字体需要一段时间,有时这些请求会超时(或者字体素材可能已经移动,导致 404)。在此期间,浏览器必须决定是应该等待字体下载以呈现需要的文本,还是不等待就提前呈现文本,然后在字体下载完成后更新呈现。火狐(4 之前)和 Opera 做的是前者,后者被称为无样式文本的闪现(FOUT)。有时,在下载网页字体前后对网页进行的调整过于激烈,以至于破坏了与网页的交互。基于 Webkit 的浏览器等待字体下载大约 3 秒钟,如果字体下载失败,则以后备字体呈现文本。

Paul Irish 写了一篇详尽的帖子,讲述了如何打败无样式文本的闪现;他在[paulirish.com/2009/fighting-the-font-face-fout/](http://paulirish.com/2009/fighting-the-font-face-fout/)概述了这样做的技巧。有几个选择。

  • 谷歌的网页字体加载器
  • 使用 font.js
谷歌的网页字体加载器

使用 Google 的 WebFont Loader,我们可以在启用 JavaScript 时完全隐藏文本,只在加载字体后通过添加基于html元素上的类的声明来呈现文本。

WebFont Loader 可以自动从几个字体库请求,这些字体库根据请求提供字体,如 Google、Ascender、Typekit、Monotype 和 Fontdeck。此外,我们可以在服务器上托管的字体上使用自定义配置。

注意,如果您使用 WebFont Loader,您不需要声明@font-face 规则。它将由 WebFont Loader 处理。

一旦对字体发出请求,WebFont Loader 就会根据资源请求的状态添加类。当请求仍在进行时,WebFont Loader 将类wf-loading添加到 HTML 元素中。如果请求失败,WebFont Loader 添加类wf-inactive;如果字体下载成功,wf-active将被添加到 HTML 元素中。

我们可以使用这些类来选择是否要避开 FOUT。例如,设置

.wf-loading h1 {         visibility: hidden; }

确保发出请求时h1保持不可见。

同样,设置

.wf-inactive h1 {         font-family: monospace; }

确保当请求的 web 字体下载失败时,使用非常匹配的本地字体来呈现h1

参见[jsfiddle.net/nimbu/HCgp8/](http://jsfiddle.net/nimbu/HCgp8/)了解如何使用网页字体加载器。

使用 font.js

创建 font.js ( [pomax.nihongoresources.com/pages/Font.js/](http://pomax.nihongoresources.com/pages/Font.js/))不是为了解决 FOUT 问题,而是为了在 JavaScript 对象模型中表示字体。尽管如此,它在动态加载字体时工作得很好,并且只在字体被加载时才呈现内容。

要使用 font.js,请在页面中结束的</head>标记之前包含font.js文件。

<script type='text/javascript' src="Font.js"></script>

然后在样式表中,使用前面讨论的防弹@font-face 规则包含 web 字体。

在适当的选择器上,添加以下声明:

#fontjs {     visibility: hidden;     font-family: 'Ultra', serif; }

在这个规则中,“Ultra”指的是使用防弹字体-字体语法的网络字体。然后,我们需要决定何时让选择器中的内容可见。在这种情况下,让我们在 body 元素获得一个名为font-loaded的类名时这样做(你将很快看到如何获得这个类名)。

.font-loaded #fontjs {     visibility: visible; }

如果 web 字体加载失败,我们还希望内容是可见的,并在发生这种情况时提供一个替代的通用字体系列。让我们在 body 元素获得一个名为font-error的类名时这样做。

.font-error #fontjs **{**     visibility: visible;     /* Our custom declarations to deal with the lack of web font availability */     font-family: sans-serif;     font-weight: bold; **}**

现在,在 JavaScript 中,我们包含了下面的代码片段,当字体加载成功或失败时,这些代码片段可以分别添加类名font-loadedfont-error

`var font = new Font();

/* Font loads successfully */
font.onload = function() {
    document.body.className = ‘font-loaded’;
};

/* Font fails to load */
font.onerror = function(err) {
 document.body.className = ‘font-error’;
}

/* Kicks off the font loading */ font.fontFamily = ‘Ultra’;
font.src = font.fontFamily;`

使用 font.js,我们可以访问一系列字体度量标准,如 ascent 和 descent 我们甚至可以获得特定字符串的指标。

不幸的是,font.js 需要canvas支持,并且在 IE8 及以下版本中不工作,这意味着 Google WebFont Loader 是防止 FOUT 的最佳选择。

进入[jsfiddle.net/nimbu/mRQpB/](http://jsfiddle.net/nimbu/mRQpB/)查看字体加载失败时的样子。

您还可以在[jsfiddle.net/nimbu/LrqPb/](http://jsfiddle.net/nimbu/LrqPb/) 加载字体时添加花式效果

使用网络字体时要记住的事情
  • 网页字体会在字体加载后重新排列整个页面。所以尽量少用。
  • Firefox 和 IE9 将从你的站点所在的服务器之外的服务器上获取网页字体,但前提是服务器明确允许。
  • 请记住您用来加载字体的技术的性能。一些字体托管服务提供了比自己服务更好的性能(见[www.artzstudio.com/2012/02/web-font-performance-weighing-fontface-options-and-alternatives/](http://www.artzstudio.com/2012/02/web-font-performance-weighing-fontface-options-and-alternatives/))。
  • 如果嵌入位没有设置为 installable ,IE9 不会识别 OpenType 字体。大多数可用的 OpenType web 字体很可能是这种情况,所以请确保使用防弹语法,这样如果 IE9 不能使用 OpenType 格式,它就可以使用 WOFF 或 EOT。
  • 如果用户在 IE6 上启用了高安全性设置,当页面使用 web 字体时会弹出一个安全框。除了将 web 字体排除在 IE6 之外,没有其他办法可以解决这个问题。
  • IE6-8 一旦遇到@font-face 规则中指定的字体,就会尝试下载该字体,这可能会减慢从同一服务器下载其他资源的速度(这可以通过从另一个服务器提供字体来减轻)。
  • 如果你使用粗体字体作为标题,确保正确设置font-weight。如果您想使用字体的粗体,如果您想在将font-weight设置为粗体([jsfiddle.net/nimbu/wcBmD/](http://jsfiddle.net/nimbu/wcBmD/))的选择器中使用它,请确保在@font-face 规则中将font-weight设置为粗体。否则,浏览器会综合地让你的粗体字体变得更粗,导致不吸引人的结果(见图 10-2 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-2。**合成的粗体显得比天生的粗体粗得多。这是它在 Firefox 中的显示方式。

寻找网页字体

有太多的字体可供选择,从免费的到非常昂贵的。在我们查看选项之前,请注意,确保您打算用作 web 字体的任何字体都有相应的许可,这一点很重要。许可证通常会声明它是否允许“嵌入”或用作网络字体。如果字体的许可证没有说明,请务必向字体提供商澄清条款。

免费网络字体

有许多网站提供免费字体。然而,并不是所有的字体都值得用作 web 字体(有些可能缺少字形,或者可能只是因为太大而不适合用作 web 字体)。这些网站提供了最好的网络字体:

  • 字体松鼠([www.fontsquirrel.com/](http://www.fontsquirrel.com/))拥有最大的免费网络字体数据库,每种字体都有方便的@font-face 工具包。它列出了一些可用作 web 字体的字体。
  • 可移动字体联盟([www.theleagueofmoveabletype.com/](http://www.theleagueofmoveabletype.com/))提供了我们可以使用的漂亮的开源字体,而不仅仅是网络字体。
  • Google Web Fonts ( [www.google.com/webfonts](http://www.google.com/webfonts))并不直接让我们下载字体文件,但它们可以通过开源许可证获得,但由 Google 托管,并通过其 web fonts API 提供服务。
  • Kernest ( [kernest.com/](http://kernest.com/))也有许多免费字体,我们可以从 Kernest 服务器下载或提供。
商业网页字体

Ralf Herrmann 有一份提供网络字体的商业代工厂名单。

FontFont Library ( [www.fontfont.com/](http://www.fontfont.com/))也开放了它的目录作为网络字体使用。字体是可以下载的,支付一次性许可费后即可使用。

Lost Type ( [losttype.com/](http://losttype.com/))提供网络字体,价格由我们指定。

字体即服务

现在有许多网站提供网络字体服务。我们需要做的就是链接到他们的样式表或脚本文件,然后在我们的样式表中使用该字体。成本因服务而异,在撰写本文时是准确的。表 10-8 列出了几个流行的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用网页字体进行设计

作为服务提供的网络字体的最大缺点是我们不能在 Photoshop comps 中轻松使用它们。然而,有一个 Adobe Photoshop CS5 插件(www.webink.com/webfontplugin)提供了几个代工厂的字体供我们在排版中使用。

Typecast ( [beta.typecastapp.com/](http://beta.typecastapp.com/))声称可以让我们使用几家铸造厂的字体在浏览器中快速创建原型。然而,在撰写本文时,这项服务尚未推出。

Chris Coyier 在[css-tricks.com/examples/IconFont/](http://css-tricks.com/examples/IconFont/)做了一个演示,概述了为什么网络字体对图标非常有用。

使用网络字体作为图标

一个新的趋势是使用字体作为图标。Simurai 有一个关于如何使用它们的很棒的教程(lab.simurai.com/buttons/)。请注意,最好将这些图标映射到它们最近的 Unicode 映射,因为屏幕阅读器倾向于将它们作为字母读出。

网页字体汇总

我们研究了 web 字体是如何产生的,以及声明 web 字体的最佳语法。我们还了解了一些加载字体的技巧,以避免无样式文本的闪现。然后,我们看了一些 web 字体的资源,以及 web 字体如何被重新用于呈现图标。

既然您已经看到了如何在 Web 上使用自定义字体,那么您无疑会对如何操作字体感到好奇。继续读!

基线

确保在使用 web 类型时使用正确的默认值,以便为所有浏览器提供最佳体验。下面是要做的第一件事:

  html { font-size: 100%; }

这将确保所有浏览器上的字体都以标准默认值开始。在桌面上,这是 16px。在移动设备上,字体的呈现取决于分辨率和设备像素比率。

您可以选择使用 Eric Meyer 的 reset.css 重置所有可能的浏览器默认字体选择,或者确保在所有浏览器上提供相同的默认浏览器体验。

我们强烈推荐第二种选择,尼古拉斯·加拉格尔和乔纳森·尼尔的 normalize.css ( [necolas.github.com/normalize.css/](http://necolas.github.com/normalize.css/))提供了现成的最佳默认设置。即使您使用的是 normalize.css,当您稍后在样式表中覆盖字体属性时,也要确保设置正确。

设置字体系列

当我们指定一个字体系列时,我们希望确保当我们选择的字体不可用时,文本以可读的格式呈现。我们可以通过设置后备通用字体来做到这一点。代码风格有一个很好的字体堆栈列表([www.codestyle.org/](http://www.codestyle.org/))。CSS 字体堆栈([cssfontstack.com/](http://cssfontstack.com/))是美学字体堆栈的另一个资源。

    body {     font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;     }

两种最常用的通用字体系列是无衬线字体和衬线字体。一定要记住它们(尤其是 sansserif 之间的连字符)!另外,记住要用引号将含有空格的字体名括起来,比如“Helvetica 新”。

iotic.com 探索的一个有趣的想法是创建一种字体,它是在他的机器上找到的所有系统字体的平均值。这是一本非常有趣的读物;在[iotic.com/averia/](http://iotic.com/averia/)找到它。

Mathias 已经非常详细地描述了哪些字体系列名称可以不加引号;在[mathiasbynens.be/notes/unquoted-font-family](http://mathiasbynens.be/notes/unquoted-font-family)找到它

设置垂直间距

设置类型时,一定要设置line-height属性。行高可以采用无单位值;这意味着任何选择器和从该选择器继承样式的元素都将它们的行高计算为无单位值和它们当前字体大小的乘积。为line-height设置一个大于 1 的无单位值是一个很好的做法,以确保你的文本总是可读的。

设置字号

使用 em 单位设置字体大小。当我们在 ems 中指定font-size时,得到的字体大小是 em 值和继承的字体大小的乘积。例如,

body { font-size: 100%; } h2 { font-size: 2em; }

导致 h2 元素的计算字体大小约为 32px。这是一种相对于基本字体大小设置字体大小的简单方法。如果我们增加基本字体大小,其他元素会自动调整。

最流行的设置字体大小的方法是使用像素。这很容易做到,但是当客户要求更大的文本尺寸时,调整所有的尺寸是非常痛苦的。但是,如果我们使用 ems,这是微不足道的。但是话说回来,如果三层嵌套和元素样式被更高特异性的选择器意外覆盖,那么使用 ems 很容易成为维护的噩梦。幸运的是,有一个更好的解决方案:rem 单元。

rem 单位

rem 单元允许我们相对于根元素(通常使用的是html元素)来设置字体大小。通过使用 rem 而不是 em,我们避免了 ems 的特殊性问题,只需改变根元素的字体大小,使文本一致地变大或变小;参见表 10-9 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们强烈建议使用 rem 单位来设置字体,并回退到 em 单位。

接下来,让我们来看看如何渲染文字是令人愉快的阅读。我们通过将字体设置为垂直节奏来做到这一点。

Jonathan Snook 有一篇关于使用快速眼动装置的很好的文章;参见[snook.ca/archives/html_and_css/font-size-with-rem](http://snook.ca/archives/html_and_css/font-size-with-rem)

使用网格进行设计

在一篇开创性的文章中,Richard Rutter 展示了建立印刷垂直节奏的秘密。他解释道:

垂直空间的基本单位是行高。建立一个适用于页面上所有文本的合适的行高,无论是标题、正文还是旁注,都是稳定可靠的垂直节奏的关键,这将吸引并引导读者阅读页面。

有两种方法可以做到这一点,一种是使用 em 单位,另一种(简单得多)是使用像素单位。以下是我们将使用垂直节奏的标记:

      <p>There were four of us—George, and William Samuel Harris, and myself, and Montmorency. We were sitting in my room, smoking, and talking about how bad we were—bad from a medical point of view I mean, of course.</p>       <p>We were all feeling seedy, and we were getting quite nervous about it.  Harris said he felt such extraordinary fits of giddiness come over him at times, that he hardly knew what he was doing; and then George said that he had fits of giddiness too, and hardly knew what he was doing.  With me, it was my liver that was out of order.</p>       <p class="aside">I knew it was my liver that was out of order, because I had just been reading a patent liver-pill circular, in which were detailed the various symptoms by which a man could tell when his liver was out of order.  I had them all.</p>

在我们继续之前,我们需要决定我们节奏的基本单位。然后,我们可以在像素单位或 em 单位中实现这个基本单位的倍数(以创建一个节奏)。为了可读性,在我们的例子中,我们希望我们的基本单位是默认字体大小的 1.5 倍。结果是 1.5em 或 24px,这取决于我们在实现中使用的单位。让我们看看这两种方法。

带像素

`body {
  /* font size is 16px */
  font-size: 100%;

/* Yay, base unit */
  line-height: 24px;
}

p {
/* total space vertically above and below each paragraph equals to one base unit: 24px  */
  margin: 12px 0;
}`

在这段代码中,我们建立了基线字体间距。现在让我们从第一段开始。我们希望它比任何其他段落都大,但仍然保持垂直节奏。

p:first-child {   font-size: 24px; }

每次声明边距、填充、边框时,确保上限值和下限值之和是基本单位的倍数。特别要注意的是,页边距折叠会扰乱你的垂直节奏,所以你需要根据应用于前一个元素的页边距仔细地组合你的页边距。

转到[jsfiddle.net/nimbu/CV2Kt/7/](http://jsfiddle.net/nimbu/CV2Kt/7/)查看应用该样式后该标记的外观。如您所见,每条线都完美地适合垂直网格。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 10-3 使用带有像素的 vertica 节奏拟合网格的文本

让我们设置最后一段有一个边框和较小的字体大小。

`p:last-child {
  font-size: 12px;

/* margin-top is already margin-collapsed to be 12px, we now need to allocate rest of the
margin to the bottom margin so in total with border-width it would be a multiple of the base
unit */
  margin: 12px 0;

/* Padding top and bottom is 12px each, total = 24px */
  padding: 12px 0;
}`

它看起来是这样的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-4。**最后一段较小,但仍适合网格。

以像素计算要容易得多。以下是如何用 em s 做到这一点。

带 ems

`/* gives us a base font-size of 16px, base line height of 24px on desktop browsers */
body { font-size: 100%; line-height: 1.5em; }

p {
/* vertical space above and below each paragraph totals to one line: 24px (0.75em = 12px)  */
   margin: 0.75em 0;
}

p:first-child {
  /* font-size is now 24px, line-height if not redeclared will be now 36px */
  font-size: 1.5em;

/* line height is redeclared, now same as font size! 24px */
  line-height: 1em;

/* vertical space above and below each paragraph totals to one line: 24px  */
  margin: 1em 0;
}

p:last-child {
  /* font size is now 12px, line height is redeclared and will be 2*12px = 24px  */
  font-size: 0.75em;
  line-height: 2em;

/* previous paragraph has margin bottom set to 12px, hence margin collapsing means we cannot
set a smaller margin-top  for this selector.  We now need to allocate rest of the margin to the bottom margin (12px/7.2px = 1.667em) so in total with border-width it would be a multiple
of the base unit */
  margin: 1em 0;

/* Padding top and bottom is 12px each, total = 24px */
  padding: 1em 0;
}`

下面是应用了这种样式的标记的外观([jsfiddle.net/nimbu/eg8D6/15](http://jsfiddle.net/nimbu/eg8D6/15))。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果您在其他地方覆盖这些元素的字体大小,网格将会混乱。在像素垂直节奏的情况下,未考虑的元素(如大小不是基本单位倍数的图像、广告、显示在表单元素中的浏览器 chrome,或动态加载的文本,如 Twitter 小部件)会导致相同的问题。

设置网格

手动设置基线网格不是一项简单的任务。我们不仅需要考虑当前元素的交互作用,还需要考虑应用了当前元素的先前元素的交互作用。经过几层嵌套,这就变成了一个非常毛的前景。我们还需要考虑空白塌陷,特别是如果较大的空白不是垂直节奏单位的整数倍。

如果我们将网格图像设置为背景,以便立即进行视觉验证,那么定义基线网格的过程就会容易得多。有许多方法可以做到这一点,但在所有这些方法中,我们都需要提供基本单元的大小。

  • 带插件 : Gridbuilder ( [gridbuilder.kilianvalkhof.com/](http://gridbuilder.kilianvalkhof.com/))根据我们提供的选项生成图像,然后我们可以将它设置为背景图像。
  • 使用 CSS 渐变:我们可以用这种方式使用重复渐变来设置网格背景图像([jsfiddle.net/nimbu/BUvMw/](http://jsfiddle.net/nimbu/BUvMw/))。第十一章更深入地讲述了渐变。
  • 使用书签工具:安德烈·汉森有一个书签工具,可以在我们使用它的页面上为我们呈现网格([peol.github.com/960gridder/](http://peol.github.com/960gridder/))。
自动化垂直节奏

没有多少工具可以创造出自动的垂直节奏,但是下面这些是有用的:

  • Iain Lamb 的排版工具([lamb.cc/typograph/](http://lamb.cc/typograph/))是理解如何应用垂直节奏的好方法。
  • 如果我们输入目标字体大小,Andrew 有一个工具([drewish.com/tools/vertical-rhythm](http://drewish.com/tools/vertical-rhythm))来计算垂直节奏的 CSS。对于大多数基本情况,这应该足够了。
  • Smashing Magazine 有一个 Photoshop 工具的综述,用于处理网格([www.smashingmagazine.com/2011/11/09/establishing-your-grid-in-photoshop/](http://www.smashingmagazine.com/2011/11/09/establishing-your-grid-in-photoshop/))。
  • Compass(位于 Sass 预处理器之上的 CSS 框架)提供了方便的垂直节奏混合,使得用垂直节奏作曲变得简单([compass-style.org/reference/compass/typography/vertical_rhythm/](http://compass-style.org/reference/compass/typography/vertical_rhythm/))。

基线网格汇总

设置基线节奏不是一件容易的事情,但是网格工具使这个过程变得更加容易,并且最终为内容的优雅呈现带来了丰硕的成果。接下来,我们将看看用 CSS3 调整字体的不同方法。现在的选择比以前多了很多!

有趣的网页类型

还记得解剖铅字课吗?本节展示了这些术语的一些实际应用。CSS3 为调整字体提供了很多支持。以下是在 CSS3 中使用 type 的一些方法。

选择字形的粗细

使用font-weight属性,我们可以设置文本渲染得更暗更重。它可以有以下值:

  • 100 to 900:这些值形成一个有序的序列,其中每个数字表示一个至少和它的前一个一样暗的权重。

  • normal:字体渲染时就好像指定了 400 的权重。

  • bold:字体的渲染就像权重被指定为 700 一样。

  • bolder: Uses a weight that is bolder than the inherited value. For example, body { font-weight: normal; } p { font-weight: bolder; }

    将所有段落元素的文本设置为大于 400 的权重。

  • lighter: Uses a weight that is lighter than the inherited value. For example, body { font-weight: normal; } p { font-weight: lighter; }

    将所有段落元素的文本宽度设置为小于 400。

bolderlighter关键字的精确映射在表 10-10 中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

有趣的特性(也是最让印刷工心痛的特性)是,浏览器为没有定义粗体或浅色值的字体生成粗体/浅色字体。例如,如果我们使用 Helvetica Neue Light,并将字体粗细设置为 800,因为在用户的计算机上没有默认可用的更粗的 Helvetica Neue Light 字体,浏览器将生成更粗的版本以在屏幕上呈现文本(参见图 10-3 )。表 10-11 列出了对font-weight的浏览器支持。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-3。**合成文本

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

选择合适的字体宽度

使用font-stretch,我们可以从一个字体系列中选择一个正常的、压缩的或扩展的字体。支持仅限于 IE9+和 Firefox 9+(参见表 10-12 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

控制文本溢出

当文本溢出它的块容器时(块容器将 overflow 设置为 visible 之外的任何值),我们可以控制如何裁剪溢出的文本。该属性在以下情况下被触发

  • The white-space property of the block element is set to nowrap

    或者

  • 一个单词比块容器的宽度长(如果是以水平文本书写的文本,如英语)。

我们可以将文本设置为在前几个可见字符后裁剪或呈现省略号(…)。图 10-4 展示了一个它如何渲染的例子。浏览器支持见表 10-13 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-4。**正文溢出:省略号在行动

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从基线垂直对齐文本

属性允许我们设置内联元素相对于其父元素的位置。注意它指的是 inline 元素。默认情况下,内联元素(如biemimgstrong等)。)与父元素的基线对齐。但是我们可以调整内联元素的位置来匹配这些选项中的几个:baseline(默认)、subsupertoptext-topmiddlebottomtext-bottominherit。我们也可以用长度单位和百分比来设置它们,就像这样:

sup { vertical-align: 30%; }

图 10-5 显示了一个例子。浏览器支持见表 10-14 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-5。**字符 1 放置在基线上方,垂直对齐设置为行高的 30%

这段代码将sup的位置从基线提升了line-height值的一个百分比。如果我们想从基线上升/下降一个固定值,我们可以使用长度单位。

sup { vertical-align: 20px; }

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

CSS3 从根本上重新定义了 vertical-align 中允许的值,以考虑除英语([www.w3.org/TR/css3-linebox/#vertical-align-prop](http://www.w3.org/TR/css3-linebox/#vertical-align-prop) ) 之外的其他语言。

控制一个单词的字母之间的空格

Letter Spacing让我们设置文本中两个字符之间的间距。负值表示两个字符之间的间距将缩短。参见图 10-6 中的示例和表 10-15 中的浏览器支持。

p { letter-spacing: 5px; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-6。**字母间距:5px

在 CSS 中,我们只能设置统一的字母间距,这将在文本中的两组字符之间添加相同的间距。为了定制这一点(调整不同字符集之间的间距),我们可以使用 lettering.js ( [letteringjs.com/](http://letteringjs.com/)),这是一个 jQuery 插件,它用一个 classname 将每个字符包装在一个 span 元素中,然后我们可以用它来调整每个字符的设置。图 10-7 展示了它的一个实例。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 10-7 。letterminations . js 曾经在特伦特·沃尔顿的博客文章trentwalton.com/2011/11/18workspace/上产生过良好的效果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 CSS3 中,已经更新为取 1 到 3 个值,每个值分别指定最佳间距、最小间距和最大间距。还没有浏览器实现这种新语法。

调整单词间距

word-spacing指定两个单词之间空格的行为。负值表示词与词之间的间距缩小。

h2 { word-spacing: 2px; }

我们也可以在内联块元素上创造性地使用这一点,以防止空白以这种方式影响它们的位置([jsfiddle.net/nimbu/UrLBk/](http://jsfiddle.net/nimbu/UrLBk/))。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 10-8 显示了另一个例子。浏览器支持见表 10-16 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-8。**行距:20px 在行动

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 CSS3 中,已经更新为取 1 到 3 个值,每个值分别指定最佳间距、最小间距和最大间距。还没有浏览器实现这种新语法。

断长词

如果一个句子包含一个牢不可破的单词(就像“antidisestablishmentarianism”),浏览器通常会在同一行中呈现它,即使它溢出了容器的宽度。我们可以使用word-wrap: break-word来告诉浏览器,如果单词太长而不适合其容器的宽度,就将其断开。图 10-9 显示了一个示例,而表 10-17 列出了浏览器支持。

h2 { word-wrap: break-word; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-9。**自动换行:自动换行。当第一个单词变宽时,它会超出容器的宽度,但是通过使用 word-wrap: break-word,第二个单词会断开以适应容器的宽度。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

控制空白和换行符

white-space属性只是选择以下选项之一来处理所选元素的文本中的空白:

  • normal:根据需要折叠空白并换行以填充尺寸(当有换行符时不需要)。
  • nowrap:空格被折叠,但行不被破坏。
  • pre:空白不折叠,只有在文本中有换行符或在生成内容的情况下有“\A”时才会换行。
  • pre-wrap:行为类似于pre,但是根据需要换行以填充尺寸,或者如果存在换行符,则换行。
  • pre-line:行为类似于pre-wrap,除了它也折叠空格和制表符。

图 10-10 显示了一个例子,表 10-18 列出了浏览器支持。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-10。**包含所有可用关键字值的空白属性

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

打印连字符

多年来,网页设计者一直试图找到一种解决方案,让他们能够用连字符漂亮地对齐文本。幸运的是,最近已经做了很多工作来控制 CSS 中的连字符。

连字符

使用hyphens属性,我们可以控制连字符的显示。它采用下列值之一:

  • none:单词不换行。
  • manual:如果单词中有换行字符,如软连字符(&shy;)或连字符(-),则单词会被换行。
  • auto:在适当的断字点断字。请注意,浏览器需要了解需要断字的文本所使用的语言,因此这只适用于声明了适当语言(通过父元素上的lang属性,可以是htmlbody)并且浏览器拥有正确断字资源的文本。

h2 { hyphens: auto; }

参见图 10-11 中的示例和表 10-19 中的浏览器支持。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-11。**连字符:自动运行

注意hyphens的初始值是手动的。对于要自动断字的单词,该属性应设置为auto

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

前往[jsfiddle.net/nimbu/Rv6vV/](http://jsfiddle.net/nimbu/Rv6vV/)观看连字符演示。

软连字符

软连字符(在 HTML 实体中表示为&shy;)用于向浏览器指示该单词可以用连字符连接的位置。这不是一个 CSS 属性,但它是目前实现跨所有浏览器工作的连字符的唯一方法。下面是一段使用了软连字符的段落:

这个词的一个稍长但不太为人接受的变体可以在艾灵顿公爵的歌曲“你只是一个老的反 disestablish ­精神主义者”[3]中找到,尽管这个词的正确结构应该是“反 disestablish ­精神主义者”(没有“主义”)。

在不需要软连字符的情况下,这一段与没有软连字符的一段呈现相同,正如你在图 10-12 中看到的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-12。**软连字符在不需要的时候不会渲染(这里两个部分看起来一样)。

但是一旦单词开始断裂,带软连字符的单词看起来就不一样了,如图 10-13 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-13。**当单词遇到换行符而需要换行时,会显示软连字符。

很难记住在文本中添加软连字符。幸运的是,我们可以使用一些工具。理想情况下,我们不应该在客户端这样做,但如果有必要,我们可以使用不再更新的 Sweet Justice ( [carlos.bueno.org/2010/04/sweet-justice.html](http://carlos.bueno.org/2010/04/sweet-justice.html))或软连字符([www.softhyphen.com/](http://www.softhyphen.com/))。表 10-20 列出了浏览器对软连字符的支持。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

控制引用字形

使用quotes属性,我们可以为每一层引号设置用于开始和结束引号的字形(从最外层到最内层)。然后,通过使用带有左引号或右引号关键字的content属性,我们可以为每个选择器设置引号。

标记:

<blockquote><p>Imagine a puddle waking up one morning and thinking, <q>This is an interesting world I find myself in — an interesting hole I find myself in — fits me rather neatly, doesn't it?</q></p></blockquote>

风格:

`blockquote { quotes:  “+” “;” “<” “>”; }

blockquote::before,
q::before { content: open-quote; }

blockquote::after,
q::after { content: close-quote; }`

图 10-14 显示了产生的文本(引用符号用黑色表示)。表 10-21 列出了浏览器支持。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 10-14。**自定义引用字形在起作用

悬挂标点符号

在文档布局工具中,我们通常可以设置标点符号,这样它们就不会干扰文本的流动。然而,这在浏览器中是不可能的。有了 CSS3,我们现在可以做到这一点!它可以采用以下值:

  • none : 无字可挂。

  • first: An opening bracket or quote at the start of the first formatted line of an element hangs. See Figure 10-15 for an example. 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    **图 10-15。**行动中的hanging-punctuation: first

  • last : 在一个元素的最后一个格式化行的末尾,一个右括号或引号被挂起。

  • force-end: A stop or comma at the end of a line hangs. See Figure 10-16 for an example. 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    **图 10-16。**行动中的hanging-punctuation: force-end

  • allow-end: A stop or comma at the end of a line hangs if it does not otherwise fit prior to justification.

    我们可以这样使用它:

    p {    hanging-punctuation: allow-end; }

  • hanging-punctuation 、w hen set,在测量线条的内容时不考虑适合、对齐或对齐。在撰写本文时,任何浏览器都不支持这一特性,但它大有可为!

控制非拉丁网页类型的渲染

CSS3 引入了许多新的属性,允许更大的灵活性和非拉丁类型的样式。这里有几个这样的特性。

断词

这设置了我们在跨行分配单词时希望单词如何断开(如果有的话)。以下是选项:

  • normal:按照通常的规则创建行。
  • break-all:在“溢出”容器宽度的每个单词处换行。这只有在我们主要使用 CJK(中文、日文、韩文的缩写)字符,并且希望文本在各行之间分布更加均匀时才有用。
  • keep-all : CJK 字符具有隐含的断点,当使用该值时不再适用。这个值意味着单词不会被打断(这对于其他脚本来说相当于正常)。
文本-强调

在 CJK 文字中,强调是由被强调的字符旁边的小符号来表示的。我们可以使用四个属性来设计和呈现这些符号:

  • 这个属性允许我们设置想要用来强调的符号种类。我们可以从可用的关键字中进行选择,或者设置我们自己的字符作为符号。h2 em { text-emphasis-style: double-circle; }
  • 我们可以让这些强调标记的颜色与正文不同。h2 em { text-emphasis-color: red; }
  • 这个属性让我们指定强调标记的位置。h2 em { text-emphasis-position: above right; }
  • text-emphasis:这个快捷属性允许我们将text-emphasis-styletext-emphasis-color设置在一起。然而text-emphasis-position依赖于文本的语言并被继承(因为它只需要被设置一次)。这是一个文本强调的演示(在 Chrome 或 Safari 5.1 中查看)。M

h2 em { text-emphasis: double-circle indianred; }

目前只有 Chrome 和 Safari 5.1+支持带–WebKit-前缀的text-emphasis

使用连字和其他 OpenType 字体功能

OpenType 格式提供了许多附加字体功能,这些功能通常只能通过 Adobe InDesign 等应用使用。在 CSS3 字体模块中,这些功能现已公开,供 web 开发人员使用。当这被实现时,我们可以在文本中使用连字、花体、小型大写字母和表格数字。语法如下:

h2.fancy {   /* enable small caps and use second swash alternate */   font-feature-settings: "smcp", "swsh" 2; }

smcpswsh是区分大小写的 OpenType 特征标签。标签的完整列表可以在[www.microsoft.com/typography/otspec/featurelist.htm](http://www.microsoft.com/typography/otspec/featurelist.htm)的 OpenType 规范中找到。swsh旁边的值 2 表示要选择的字形的索引。

Firefox 4 有一个稍微不同的font-feature-settings实现。

h2.fancy {   -moz-font-feature-settings: "smcp=1,swsh=2"; }

表 10-22 列出了浏览器支持。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

阅读 John Daggett 在[jsfiddle.net/nimbu/Rv6vV/](http://jsfiddle.net/nimbu/Rv6vV/)发表的描述 CSS3 字体特性的文章,以及 Fontdeck 关于字体特性([blog.fontdeck.com/post/15777165734/opentype-1](http://blog.fontdeck.com/post/15777165734/opentype-1))和 Internet Explorer 演示([ie.microsoft.com/testdrive/Graphics/opentype/opentype-fontbureau/index.html](http://ie.microsoft.com/testdrive/Graphics/opentype/opentype-fontbureau/index.html)))的博客文章。

总结

我们展示了网页排版从黑暗时代到现在的历史,以及它过多的控制字体的特性。我们展示了@font-face 是如何发展的,以及在页面上调整字体的不同方式。在这一章中,你还学习了根据相对和绝对单位的节奏来排版。我们还简要了解了控制非拉丁字体的一些属性。

延伸阅读

  • CSS 文本模块([dev.w3.org/csswg/css3-text/](http://dev.w3.org/csswg/css3-text/)):本章中的一些特性在这里有更详细的描述。
  • CSS 生成内容模块([dev.w3.org/csswg/css3-content/)](http://dev.w3.org/csswg/css3-content/))):关于quotes属性的更多信息可以在这个模块中找到。
  • CSS 字体模块([dev.w3.org/csswg/css3-fonts/](http://dev.w3.org/csswg/css3-fonts/)):这个模块深入解释了@font-face 规则以及可用于 OpenType 格式的字体特性设置
  • CSS 线条布局模块([dev.w3.org/csswg/css3-linebox/](http://dev.w3.org/csswg/css3-linebox/)):这里将详细讨论 CSS3 中提出的垂直对齐。
  • “用垂直节奏作曲”([24ways.org/2006/compose-to-a-vertical-rhythm](http://24ways.org/2006/compose-to-a-vertical-rhythm)):解释垂直节奏的开创性文章。
  • “防弹@font-face 语法”([paulirish.com/2009/bulletproof-font-face-implementation-syntax/](http://paulirish.com/2009/bulletproof-font-face-implementation-syntax/)):记录了一年来适用于所有浏览器的字体规则的演变。

十一、让 CSS3 属性发挥作用

到目前为止,在本书的后半部分,你已经复习了 CSS 基础知识;了解了新的选择器;创造了漂亮、灵活的布局;漫步在网络排版的世界里。现在是时候让更多的 CSS3 属性发挥作用,并把这些微妙的东西添加到您的站点中。

在这一章中,我们将研究新的颜色模型、透明度和背景属性;我们还将展示如何应用多种背景、边框、阴影和渐变。因此,无论您是想要创造一个视觉上令人惊叹的前沿设计,还是一个疯狂、喧闹、夸张的 Web 2.0 怪物,我们都支持您。

颜色和透明度

我们习惯于在样式表中用关键字(redblue)或十六进制值(#fff#ffffff)来表示颜色值。CSS3 颜色模块([j.mp/css3color](http://j.mp/css3color)<sup>1</sup>)引入了两种写入颜色值的新方法:RGBa 和 HSLa。在决定使用哪种方法之前,我们需要了解 RGB 和 HSL 之间的区别。


1

RGB

毫无疑问,你以前听说过 RGB。为了清楚起见,它表示红色、绿色和蓝色颜色模型,在该模型中,您使用每种颜色的三个数值来创建颜色。回想一下艺术学校,RGB 是一种加色颜色模型,通过将三原色相加来创建颜色。这与十六进制计算的工作方式相同,将三个值相乘,不同之处在于这些值以不同的方式表示。RGB 使用 0-255 之间的数字。图 11-1 显示了 Photoshop 的拾色器中指定的 RGB 值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-1。**Photoshop 中的拾色器

我们习惯于用 CSS 以三种不同的方式来描述颜色,比如纯蓝色:名称、简写的十六进制代码和完整的十六进制代码。

color: blue; color: #00f; color: #0000ff;

要使用 RGB 实现颜色,可以使用rgb关键字,后跟括号中的 RGB 值。为了用 RGB 来描述纯蓝色,我们可以用数值或百分比来表示红色、绿色和蓝色。RGB 值实际上是 CSS 2.1 的一部分,但直到最近才被普遍使用。这里是数值和百分比值(注意,其余的示例将使用数值)。

color: rgb(0,0,255); color: rgb(0,0,100%); /* color: rgb(red, green, blue); */

注意:不要忘记rgb不一定要和color属性一起使用;你可以在 CSS 中声明颜色值的任何地方使用它,比如backgroundborder-color

你可以马上开始在工作中使用 RGB 值。从 IE6、Safari 3、Firefox 3、Chrome 和 Opera 10 以上的所有浏览器都支持它。

RGBa 透明度

通过向属性添加第四个值,可以控制透明度。第四个值,RGBa 中的“a”,代表 alpha。它的作用和在 Photoshop 中改变 alpha 通道完全一样。

要实现 RGBa,你需要把你的rgb关键字改成rgba;这允许我们设置透明度。“a”(alpha)值通过添加一个介于 0 和 1 之间的数字来设置(其中 0 表示完全透明,1 表示完全不透明)。值 0.6 相当于将透明度设置为 60%。

color: rgba(0,0,255,0.6); /* color: rgba(red, green, blue, alpha); */

图 11-2 显示了从完全不透明(1)到完全透明(0)的不同 alpha 透明度值。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 11-2。 RGBa 透明行动

许多知名网站已经开始使用 RGBa。一个最好的例子就是蒂姆·范达姆([j.mp/timvd](http://j.mp/timvd)<sup>3</sup> ) ( 图 11-3 )设计的 24 种方式([j.mp/24ways.org](http://j.mp/24ways.org)<sup>2</sup>)。


2

3

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-3。**24 路站点大量使用 RGBa 建造。

浏览器对 RGBa 的支持不像对 RGB 那样广泛。除了 IE 6-8 之外,它在前面提到的所有浏览器中都受支持。然而,IE9 支持 It 。为了迎合那些功能较差的浏览器,在你的样式规则中添加一个纯色选项。

a {   color:rgb(0,0,255); /* Fallback for less capable browsers */   color:rgba(0,0,255,0.6); }

浏览器应用它们理解的最后一个属性,所以最后添加关键字RGBa确保了更有能力的浏览器将应用透明性。那些不理解RGBa的人会简单地忽略它并实现他们理解的属性(第一个color值)。如果你不能用纯色,你可以用同样的方法添加一个备用的 PNG。

article {   background:url(white50.png); /* Fallback for less capable browsers */   background:rgba(255,255,255,0.6); }

能够在不使用图像的情况下编辑 alpha 透明度意味着我们也可以将其应用于边框和轮廓。此外,在需要更改时只编辑 CSS 比返回 Photoshop 更新多个图像更容易、更快捷。最后,作为一个幸运的副作用,服务器请求的数量减少了(因为你没有加载图像),这将使你的网站更快。

使用 CSS3 添加颜色的另一种方法是使用 HSLa(色调、饱和度、亮度和 alpha)。HSL 比 RGB 更直观。你可以通过考虑一个色轮,然后调整饱和度和亮度值,直到我们找到我们想要的确切的颜色,来对初始颜色做出明智的猜测。

色调值由 0-360 度的值表示。查看图 11-4 中的色轮,我们可以看到红色由 0 度和 360 度表示,其他两种原色的间隔为 120 度(绿色= 120 度,蓝色= 240 度)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-4。**blulob.com HSLa 色轮

HSL 符号中的第二个值是饱和度,或特定颜色的强度。这是一个百分比值,描述为与灰色相比的色彩丰富度,其中 0 表示灰度,100%表示全色饱和度。第三个值代表亮度,用百分比表示,0 表示暗或黑色,50%表示正常亮度,100%表示白色。

为了使用 HSLa 获得纯红色,我们需要结合色调(0 或 360 度)、饱和度(100%,完全饱和)和亮度(50%,正常亮度)的三个值。此外,alpha 通道应设置为 1,以确保颜色完全不透明。

hsla(0,100%,50%,1) /* hsla (hue, saturation, lightness, alpha) */

注意:HSLa 颜色值是度数和百分比加上一个 alpha 通道的混合。

图 11-5 显示了通过编辑色调、饱和度、亮度和阿尔法值创建的纯红色示例的多种变化。为了得到这个想法,你自己尝试一下是值得的;一本黑白的书并不总是传达全部的效果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-5。**演示如何使用 HSLa 实现色彩变化

与 RGBa 一样,除了 IE 6-8 之外,大多数主流浏览器(包括 IE 9)都支持 HSLa。

对于只使用 CSS 的设计人员来说,计算 RGB 值可能很困难。相比之下,HSL 允许我们为色调选择一种颜色(0-360 之间的值),然后使用饱和度和亮度值对其进行优化。这一切都是最少的麻烦,并节省了不断跳回到 Photoshop 来检查颜色值是正确的。

注:Brandon Mathis 的 HSL 拾色器([hslpicker.com/](http://hslpicker.com/))就是这样一个方便的小工具,用来挑选色调,调整饱和度和亮度。它还提供您选择的颜色的十六进制和 rgb 等效值。

不透明度

Alpha 透明度不是创建透明元素的唯一方式;另一种方法是使用opacity属性。它的工作方式类似于 RGBa 或 HSLa 中的 alpha 通道,采用 0 到 1 之间的值,不同之处在于它是为属性指定的唯一值。这意味着你仍然需要使用另一个属性来声明颜色,比如background-color或者color。要将article的背景设置为 50%不透明,我们可以使用:

article {   background-color:#fff;   opacity:0.5; }

如图 11-6 中的所示,问题在于当opacity被设置时,它影响了包含在父元素中的所有子元素的透明度。相比之下,RGBa 和 HSLa 只影响其应用的元素和属性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-6。**左边显示不透明的文章,右边显示应用了 50%不透明的文章。

如果可以选择,在大多数情况下,你会希望使用 RGBa 或 HSLa 来增加透明度。当你想让一个元素淡出到背景中,直到与它交互(例如广告或表单)时,这个功能会很有用。

opacity值与:hover:focus等伪类一起使用和更改可能会很有效。你也可以把它用于访问过的链接,一旦访问过,就把它们淡入背景。使用 RGBa 或 HSLa 可以达到同样的效果,但是如果你的站点上的链接是多种颜色的,使用opacity将会把它们都作为目标,而不需要你为每个颜色实例编写规则。

a:visited {   opacity:0.5; }

图 11-7 显示了这一点。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-7。**一个不透明度为 50%的访问链接的例子(在这个例子中“许多动物被推向天空”)

注意opacity可以在除 IE 6-8 以外的所有浏览器中工作。有特定的过滤器可以让opacity在 IE 中工作,但是,正如在第七章中强调的,我们只会把它们作为最后的手段。

正如我们所见,CSS3 提供了在设计中添加和调整颜色的新方法。您已经看到了如何实现不透明度、RGB 和 HSL 颜色模型,以及如何添加 alpha 透明度。何时何地使用 RGBa、HSLa 和 opacity 由你决定,但毫无疑问,这三者在我们的 CSS 锦囊中都有一席之地。

背景

具有广泛实现的最有趣的 CSS3 模块之一是背景和边框模块([j.mp/css3background](http://j.mp/css3background)<sup>4</sup>),目前是一个候选推荐。我们将在本章后面回到边框,但同时,让我们讨论背景剪辑,多重背景,以及设置背景大小的选项。


4

背景-剪辑

我们习惯于看到背景延伸到他们的边界(图 11-8 )。背景和边框模块中引入的是background-clip属性,它允许我们指定背景是否延伸到边框中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-8。**背景图像延伸到一个元素的边界

background-clip可以取以下三个值:

  • border-box
  • padding-box
  • content-box

如果background-clip未声明,则border-box值为默认值(图 11-8 )。

padding-box值添加到属性中会剪切要在边框内呈现的背景。

#introduction {   border:5px dashed rgb(255,0,0);   background:rgba(255,255,255,0.7) url(img/bg-moon.jpg) 50% 50%;   padding:0 20px;   color:rgb(255,255,255);   -moz-background-clip:padding;   background-clip:padding-box; }

图 11-9 显示了边框内部渲染的背景。Opera 10.5+,IE 9+,Safari 5+,Firefox 4+,Chrome 5+都实现了没有厂商前缀的background-clip属性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-9。**应用了填充框值的 CSS3 背景剪辑属性

第三个值content-box,将背景裁剪到框的内容区域(图 11-10 ),这是填充内部的区域。

#introduction {   border:5px dashed rgb(255,0,0);   background:url(img/bg-moon.jpg) 50% 50%;   padding:0 20px;   color:rgb(255,255,255);   background-clip:content-box; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-10。**应用了内容框值的 CSS3 背景剪辑属性

背景-起源

background-origin允许我们指定给定元素的background position的起点。它可以采用与background-clip相同的值。例如,如果您的背景位于左上角(0,0),默认的padding-box ( 图 11-11 )值将背景定位到填充的外边缘(也是边框的内边缘)。

#introduction {   border:5px dashed rgb(255,0,0);   background:url(img/bg-moon.jpg) 0 0;   padding:0 20px;   color:#fff;   background-clip:border-box;   background-origin:padding-box; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-11。**应用了填充框值的 CSS3 背景-原点属性

background-clip一样,background-origin在 Opera、Safari、Firefox、Chrome 和 IE 9 中被原生支持。

注意:background-clipbackground-origin的值不必相同。

border-box值将背景定位在边框的外边缘(图 11-12 )。根据边框的宽度,这种变化可能非常微妙。

#introduction {   border:5px dashed rgb(255,0,0);   background:url(img/bg-moon.jpg) 0 0;   padding:0 20px;   color:#fff;   background-clip:border-box;   background-origin:border-box; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-12。**应用了边框值的 CSS3 背景-原点属性

background-origin可以取的最后一个值是content-box,,它将背景起点设置为内容的边缘,或者填充的内边缘(图 11-13 )。

#introduction {   border:5px dashed rgb(255,0,0);   background:url(img/bg-moon.jpg) 0 0;   padding:0 20px;   color:#fff;   background-clip:border-box;   background-origin:content-box; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-13。**应用了内容框值的 CSS3 背景来源属性

尽管有时很难被注意到,但你可能会发现background-origin是一个值得的选择,可以替代使用像素定位的背景图像,这取决于你想要达到的效果。

背景尺寸

属性可以用来简化 web 设计者从时间(好吧,也许只是互联网)开始就一直在纠结的问题之一。问题是:不管浏览器窗口大小或屏幕分辨率如何,都需要全尺寸的背景图像,而不必依赖 Flash 或 JavaScript。解决方案是:background-size属性。

顾名思义,它允许您指定背景图像在 X(水平)和 Y(垂直)轴上的大小。这意味着,如果你正在构建一个流体设计,你可以使用background-size来确保你正在使用的任何背景图像根据视窗的大小或浏览器的宽度进行缩放。

它可以为宽度和高度以及关键字autocontaincover取两个值。宽度和高度值可以用像素或百分比表示。第一个值是宽度,第二个值是高度。将background-size设置为 85%会产生如图图 11-14 所示的效果。

html {   background-image:url(img/earth1.jpg);   background-position:50% 50%;   background-repeat:no-repeat;   background-attachment:fixed;   background-size:85% 85%;   /background-size: width height */ } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-14。**宽度和高度为 85%的 CSS3 背景大小属性

不用设置高度值;实际上,如果没有设置高度,默认值就是auto。在这种情况下,这种影响微乎其微。

类似前面提到的后台属性,Opera、Safari、Firefox、Chrome、IE 9 都支持background-size

contain关键字缩放背景并保持其纵横比。背景将采用最大尺寸,其宽度高度能够适合它所应用的元素(在我们的例子中是html元素)。这确保了在使用contain时图像的任何部分都不会被剪切。如果你的容器对于图像来说太大了,你必须确保你的图像淡入一种你可以用作背景默认值的平面颜色(图 11-15 )。您可以使用逗号分隔值来“包含”X 轴或 Y 轴(例如contain, 250px),或者单独使用contain关键字来包含 X 轴或 Y 轴)。

此外,如果没有设置宽度和高度值,它们都被假定为auto,背景尺寸与使用co ntain 的效果相同。

html {   background-image:url(img/earth1.jpg);   background-position:50% 50%;   background-repeat:no-repeat;   background-attachment:fixed;   background-size:contain; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-15。**应用了包含值的 CSS3 背景大小属性

另一方面,cover关键字,总是接管元素的整个背景。它会随着浏览器窗口大小和形状的改变而调整大小,但可能会剪切图像的一些边缘(图 11-16 )。

html {   background-image:url(img/earth1.jpg);   background-position:50% 50%;   background-repeat:no-repeat;   background-attachment:fixed;   background-size:cover; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-16。**应用了封面值的 CSS3 背景大小属性

斯蒂芬妮·雷维斯在的一篇文章中深入探讨了背景尺寸。net 杂志([j.mp/bgsize](http://j.mp/bgsize)<sup>5</sup>)和链接到她丈夫格雷格为测试封面而创建的有用工具,并包含关键词([j.mp/bgsizetool](http://j.mp/bgsizetool)<sup>6</sup>)。使用它可以快速说明不同的关键字如何产生不同的效果。


5

6

此外,在一篇名为 List Apart ( [j.mp/supersizebg](http://j.mp/supersizebg)<sup>7</sup>)的文章中,Bobby van der Sluis 解释了如何结合background-size和媒体查询(见第九章)来确保你的背景在较低的屏幕分辨率下不会缩小得太小。请务必阅读这篇文章,并运用 Bobby 的一些技巧。

最后,关于所有背景属性、值、浏览器支持等的有用参考是 Estelle Weyl 的深入指南“你可能想知道的关于 CSS 背景属性的一切:用浏览器支持和到示例和测试用例的链接解释 w3c 规范”([j.mp/estellebg](http://j.mp/estellebg)<sup>8</sup>)。好吧,也许这不是全部,因为它没有涵盖我们接下来要看的多种背景。

多重背景

毫无疑问,你见过 Clearleft 的 Silverback 应用([j.mp/gorillaux](http://j.mp/gorillaux)<sup>9</sup> ) holding page ( 图 11-17 )这样的网站。由 Paul Annett ( [j.mp/nicepaul](http://j.mp/nicepaul)<sup>10</sup>)创建的这个网站使用不同的 PNG 透明背景的百分比来放置几个div层,以创建深度的幻觉。当调整浏览器窗口大小时,用户会看到视差([j.mp/whatisparallax](http://j.mp/whatisparallax)<sup>11</sup>)效果,因为背景图像会移动以保持它们在浏览器中的比例。

诸如此类的效果往往会创建许多没有任何含义的不必要的标记(由于保存在div s 中)。如果我们能去掉那些无关的标记会怎么样?你猜怎么着?有了 CSS3 多背景,我们可以。


7 [www.alistapart.com/articles/supersize-that-background-please](http://www.alistapart.com/articles/supersize-that-background-please)

8

9

10

11

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 11-17。【Clearleft 的 Silverback 应用的原始持有页面

在 CSS3 背景和边框模块中指定的是向单个元素添加多个背景的能力。background-image或简写background属性的逗号分隔值的数量定义了应用的背景数量。我们将向您展示使用background -image 和background的例子,所以不要担心混淆两者。对于这些例子,我们将使用三张图片(图 11-18 )并将它们层叠在一整页背景的前面。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-18。**三个独立的图像

首先,让我们看看目前为止的 CSS。我们已经在html元素上设置了一个背景图像,并将其background-size属性设置为整个浏览器窗口的cover(图 11-19 )。

html {   height:100%;   background-image:url(img/bg-cosmos.jpg);   background-repeat:no-repeat;   background-attachment:fixed;   background-size:cover; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-19。**你的起点:应用于 html 元素的背景。

现在我们要给body元素添加多重背景。我们也可以将它们添加到html元素中,但是使用另一个元素可以为功能较差的浏览器提供更容易的维护和更好的后备。

为了添加我们的第一张背景图片,我们将使用 CSS 2.1 中常见的标准符号。bodyheight设置为 100%,以确保它足够高,适合我们的图像。

body {   height:100%;   background-image:url(img/planet1.png);   background-repeat:no-repeat;   background-position:50% 30%; }

图 11-20 显示了第一张背景图片的位置。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-20。**一个应用于主体元素的背景图像

为了将第二个背景添加到body元素中,我们为每个背景属性添加了一个额外的值,用逗号将它们与第一个属性隔开。然后,我们对background-repeatbackground-position属性重复这些步骤。

body {   height:100%;   background-image:url(img/planet1.png), url(img/planet2.png);   background-repeat:no-repeat, no-repeat;   background-position:50% 30%, 15% 90%; }

注意第二幅图像是如何出现在第一幅图像下面的(图 11-21 )。这在规范中有定义:

列表中的第一幅图像是离用户最近的层;下一张画在第一张的后面,依此类推。背景颜色(如果存在)绘制在所有其他层的下方。

[www.w3.org/TR/css3-background/#layering](http://www.w3.org/TR/css3-background/#layering)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-21。**应用于 body 元素的两个背景图片。

如您所见,当声明多个值时,每个属性中的每个值都用逗号分隔。然而,我们可以通过删除background-repeat的一个no-repeat值来稍微简化我们的例子。这是因为如果没有应用多个值(本例中是第二个),浏览器会被告知重复第一个值。

body {   height:100%;   background-image:url(img/planet1.png), url(img/planet2.png);   background-repeat:no-repeat;   background-position:50% 30%, 15% 90%; }

相比之下,如果我们不小心忘记添加第二个background-image值,但确实包含了两个background-position值,浏览器将呈现第一个背景图像的另一个实例,在两个位置重复出现(图 11-22 )。这是因为浏览器重复了background-image属性的第一个值。

body {   height:100%;   background-image:url(img/planet1.png); /* Oops we've forgotten to add our second image! */   background-repeat:no-repeat;   background-position:50% 30%, 15% 90%; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-22。**一个背景图像的两个实例

不想再犯同样的错误,让我们确保在添加第三个图像时添加所有的背景值。这一次我们将使用简写 CSS 符号,使用background属性。它以完全相同的方式工作;您只需用逗号分隔每组值。

body {   height:100%;   background:url(img/planet1.png) 50% 30% no-repeat, url(img/planet2.png) 15% 90% no-repeat, url(img/planet3.png) 75% 20% no-repeat; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-23。**应用于 body 元素的三个背景图片。

现在你有了:三张背景图片应用到一个元素上(图 11-23 )。使用百分比值的美妙之处在于,当你调整浏览器大小时,图像会开始移动并隐藏在彼此后面(图 11-24 ),就像银背网站中的视差效果一样。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-24。**在一个小的浏览器窗口中显示多个背景

浏览器对多种背景的支持范围很广。它可以在 Safari 5、Chrome 5、Opera 10.5、Internet Explorer 9 和 Firefox 3.6 中运行。不过,有一个问题(不是一直都有吗?).如果浏览器不支持多种背景,它不会渲染其中任何一种。由于这个原因(这取决于你的设计),你可能想把最重要的背景图像单独放在一行,以确保至少有一个背景被渲染。

body {   height:100%;   background:url(img/planet1.png) 50% 30% no-repeat;   background: url(img/planet1.png) 50% 30% no-repeat , url(img/planet2.png) 15% 90% no-repeat, url(img/planet3.png) 75% 20% no-repeat; }

这是一个相对简单的技术,你可以从今天开始使用。请记住,您不必只在htmlbody上使用多个背景图像;它们可以应用于任何元素。帕特里克·劳克创造了一个如何使用 CSS3 的多重背景([j.mp/laukedoors](http://j.mp/laukedoors)<sup>12</sup> ) ( 图 11-25 )重现滑动门效果的例子。Patrick 没有像 Douglas Bowmans 2003 original ( [j.mp/aladoors](http://j.mp/aladoors)<sup>13</sup>)那样在标记的不同部分使用不同的背景图像,而是简单地在元素上使用多种背景来显示左侧、右侧和中央的背景图像。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-25。**帕特里克·劳克的多重背景滑动门示例

当然,如果我们有办法很容易地制作圆角盒子,帕特里克的例子会更容易制作……哦,多方便啊!下一节将介绍背景和边框模块的另一半:边框。

边框

全世界网页设计师的呼声已经被听到。我们不再需要单调地添加额外的标记或切割额外的图像,只是为了创造一些小细节,比如圆角,让我们的设计更有说服力。请看border-radius,因为它为我们提供了仅使用 CSS 的力量来添加原生圆角的能力。

背景和边框模块简直不能停止给予,你不觉得吗?它也让我们能够添加图像到我们的边界,我们稍后会看到。首先,让我们看看实现border-radius

边框半径

给任何元素添加圆角现在都可以通过简单地编写几行 CSS 代码来实现。我们不再需要在我们的标记中添加额外的span或者使用 JavaScript 来重新创建一个非常简单的任务。这里是简写的border-radius属性,以及各个角落的属性,如border-top-left-radius

深入研究记住半径是圆直径的一半(图 11-26 ),我们可以通过为每个角指定一个值来实现元素上的相等圆角。

#introduction {   border-top-left-radius: 20px;   border-top-right-radius: 20px;   border-bottom-right-radius: 20px;   border-bottom-left-radius:20px; }


12

13

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-26。**半径是圆直径的一半。

在 Chrome 5、Safari 5、Firefox 4、Internet Explorer 9 和 Opera 10.5 中,这种标记不需要供应商前缀。

注意:如果你不喜欢自己为所有浏览器编写这些长值,你可以使用像[border-radius.com](http://border-radius.com)这样的工具来自动化这个过程。输入你的角值,它将为你创建 CSS。

我们可以像使用marginpadding一样使用简写的border-radius属性,而不是总是为每个单独的角写出四个属性。我们的简化标记如下所示:

#introduction {   border-radius:20px 20px 20px 20px; }

你现在可能已经猜到了,就像marginpadding在写速记 CSS 时可以使用一个、两个、三个或四个值一样(参见第七章)。它们像这样影响角落:

  • 一个值:所有四个角的半径相同。
  • 两个值:第一个值是左上和右下,第二个值是右上和左下。
  • 三个值:第一个值是左上,第二个值是右上和左下,第三个值是右下。
  • 四个值:按左上、右上、右下、左下的顺序。

因为在我们的例子中所有角的边界半径是相同的,我们可以将我们的规则简化为如下:

#introduction {   border-radius:20px; }

前面的三个例子都获得了相同的结果(图 11-27 ),我们只是使用简写属性和值来简化代码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-27。**边框半径相等的盒子

border-radius值可以应用为 ems、像素和百分比。也可以在背景图像存在的情况下应用(图 11-28 )。

#introduction {   background:rgba(0,0,0,0.3) url(img/bg-moon.jpg) 50% 50% ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fgitee.com%2FOpenDocCN%2Fvkdoc-html-css-zh%2Fraw%2Fmaster%2Fdocs%2Fbegin-h5c3-web-evo%2Fimg%2FU002.jpg&pos_id=img-4ql4N1oz-1723651992740) no-repeat;   border-radius:2em; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-28。**带有边框半径和背景图像的方框

更复杂的是(也是为了使属性更加灵活和有用),边界半径可以有两个长度值:一个用于 X 轴(水平),一个用于 Y 轴(垂直)。这使我们能够创建椭圆形状。水平值和垂直值之间用正斜杠(/)分隔。斜线前的值代表水平半径,斜线后的值代表垂直半径。图 11-29 显示了结果。

#introduction {   background:rgba(0,0,0,0.3) url(img/bg-moon.jpg) 50% 50% ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fgitee.com%2FOpenDocCN%2Fvkdoc-html-css-zh%2Fraw%2Fmaster%2Fdocs%2Fbegin-h5c3-web-evo%2Fimg%2FU002.jpg&pos_id=img-Mn9zjrHK-1723651992740) no-repeat;   border-radius:2em / 6em; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-29。**具有边框半径以及不同水平和垂直半径值的框

如果您愿意,可以在水平和垂直方向上为每个角设置不同的半径。这可以通过使用简写border-radius和声明八个值(四个和四个由斜杠分隔)或使用单个角属性(border-top-left-radius)来编写,其中两个值由空格分隔而没有斜杠。这两个例子对div ( 图 11-30 )有完全相同的效果。

速记:

#introduction {   background:rgba(0,0,0,0.3) url(img/bg-moon.jpg) 50% 50% ![Images](https://gitee.com/OpenDocCN/vkdoc-html-css-zh/raw/master/docs/begin-h5c3-web-evo/img/U002.jpg) no-repeat;   border-radius:2em 4em 6em 8em / 9em 7em 5em 3em; }

单个角属性:

#introduction {   background:rgba(0,0,0,0.3) url(img/bg-moon.jpg) 50% 50% ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=https%3A%2F%2Fgitee.com%2FOpenDocCN%2Fvkdoc-html-css-zh%2Fraw%2Fmaster%2Fdocs%2Fbegin-h5c3-web-evo%2Fimg%2FU002.jpg&pos_id=img-Ahh1MQig-1723651992741) no-repeat;   border-top-left-radius: 2em 9em;   border-top-right-radius: 4em 7em;   border-bottom-right-radius: 6em 5em;   border-bottom-left-radius: 8em 3em; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-30。**每个角的水平和垂直半径具有不同边框半径值的框

将边框半径直接应用于 IMG 元素

如果您想将border-radius直接应用到imgvideo元素,请注意:在任何浏览器中,边框半径都不能正确地裁剪图像(图 11-31 )。最好的解决方案是通过将样式应用到外部的figurediv来解决这个问题。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-31。**直接在 img 元素上的边界半径

记住,你不必仅仅用border-radius来表示div s、article s 或sections;它也可以应用于锚点、输入,甚至是表格。如果你真的感受到了border-radius的爱,没有什么能阻止你全力以赴,创造圆形、椭圆形或更多的形状来为你的设计增添趣味。

边框-图像

如您所料,Border image 允许您指定一个图像作为元素的边框。我们将解释border-image的简写版本,但是如果你想单独使用特定的属性,细节在背景和边框模块([j.mp/css3background](http://j.mp/css3background)<sup>14</sup>)中提供。

使用单个图像来创建边界图像,然后沿着各种轴对该图像进行切片、重复或拉伸,使边界围绕元素。换句话说,使用四条线将图像分成九个部分,就像你在创建一个十字板一样,如图图 11-32 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-32。**九层重叠的边框图像

然后,四个角切片用于创建元素边框的四个角。剩下的四个边缘切片被border-image用来填充元素边界的四个边。然后,指定切片的宽度,以及是否希望它们重复或拉伸以跨越元素边的整个长度。中间的切片,如果不是空白的,将填充应用了border-image的元素的背景。

基本的border-image属性语法是

border-image: <image> <slice> <repeat>

在哪里

  • image是用作边框的图像的 URL。
  • slice是切片大小的四个百分比或数字值。
  • repeat是为了重复而处理边框的方式。这可以从roundstretchspace,repeat.中取两个值

14

注意:切片不必相等,大小完全由作者决定。欲了解更多详情,请参考规范的边界图像部分([j.mp/borderimage](http://j.mp/borderimage)<sup>15</sup>)。

在图 11-32 中,每块瓷砖的宽度为 15px。这是我们将与border-image属性一起使用的切片值。因此,我们也将把border-width属性声明为 15px。我们希望边缘瓷砖重复,所以我们将使用repeat关键字。

考虑到上述所有情况,要应用图 11-33 中的所示的边界图像,使用以下代码:

#introduction {   border-width:15px;   border-image:url(img/border1.png) 15 15 15 15 repeat; }

结果如图图 11-33 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-33。**边界图像在歌剧中的应用


15

因为我们的div的尺寸,使用repeat不是很有效,一些图案会消失在角落图像后面。然而,如前所述,我们有四个拉伸选项

  • round:图像重复填充该区域。如果不能容纳全部图块,图像会相应地缩放。
  • stretch:图像被拉伸以填充该区域。
  • repeat:图像重复填充该区域。
  • space:图像重复填充该区域。如果所有的图块都放不下,图像会被隔开以填充该区域。

我们最多可以为 repeat 添加两个值:第一个值用于水平边框,第二个值用于垂直边框。我们现在将把stretchround值应用到我们的例子中。因为我们的切片是相等的,所以我们也可以将切片值的数量从四个减少到一个。

#introduction {   border-width:15px;   -moz-border-image:url(img/border1.png) 15 stretch round;   -webkit-border-image:url(img/border1.png) 15 stretch round;   border-image:url(img/border1.png) 15 stretch round; }

图 11-34 显示了stretchround值是如何应用于我们的div的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-34。**Opera 中应用了 stretch 和 round 关键字的边框图像。

Opera、Chrome、Safari 和 Firefox 都支持border-image属性。Internet Explorer 目前不支持border-image,目前任何 IE 10 平台预览版都不支持。

注:Eric Meyer,一个对 CSS 略知一二的人,在 2011 年 1 月写了一篇题为“边界成像”的文章,他向读者提出了一个挑战,使用一张 5px 乘 5px 的图像创建一个边界。有趣的是,就目前的规范而言,这是不可能的,但认为它应该是完全合理的。请记住 Microsoft Publisher 是如何允许您添加边框的。从评论来看,这个规范似乎不会改变。然而,博客文章、评论和邮件列表条目都很有趣。

作为深思熟虑、勤奋的工匠,你无疑想知道当你把border-imageborder-radius结合在一起时会发生什么。嗯,正如你在图 11-35 中看到的,当半径被应用到背景时,边界图像保持不变。如果您的设计需要解决这个问题,只需在边框图像图形的四个角切片中重新创建圆角即可。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-35。**应用了边框半径的边框图像

虽然创建疯狂的边界图像有很多乐趣,但请确保您不会退回到一个由 CSS3 构建的 geocities 风格设计组成的平行世界。


16

落下阴影

啊,阴影。每个设计师在构思创意概念时的“必备”。这里有一个关于阴影的专业建议:如果当一个设计师在他们的 Photoshop 排版中使用默认的投影,找一个新的设计师。

曾经,加上圆角和渐变,给盒子添加阴影是一场噩梦。有了 CSS3 的背景和边框模块中的box-shadow属性,就不再是这样了。

方框-阴影

向元素添加box-shadow非常简单。它最多可以有六个值:水平偏移(X)、垂直偏移(Y)、模糊、扩散距离、颜色和一个可选的inset关键字来将阴影从外部变为内部。

box-shadow:inset [offsetX offsetY <blur> <spread> <color>];

这听起来很复杂,所以让我们通过查看对box-shadow的最低要求来了解一下,这是两个偏移值。如果愿意,可以使用负偏移值。正值分别向右下方画阴影,负值向左上方画阴影。你选择的组合由你决定(还有你的假光源从哪里来!).

#introduction {   border:5px solid rgba(0,0,0,0.7);   background:rgba(255,255,255,0.7);   padding:0 20px;   border-radius:20px;   box-shadow:15px 15px; }

通过不包含颜色值,box-shadow将采用浏览器指定的颜色,所以让我们通过使用rgba向示例添加一种颜色。

#introduction {   border:5px solid rgba(0,0,0,0.7);   background:rgba(255,255,255,0.7);   padding:0 20px;   border-radius:20px;   box-shadow:15px 15px rgba(0,0,0,0.4); }

如果不指定模糊半径值,阴影将不会模糊,因此边缘会很清晰。模糊半径是我们符号中的第三个值(在这个例子中是 10px)。模糊半径不能使用负值。

#introduction {   border:5px solid rgba(0,0,0,0.7);   background:rgba(255,255,255,0.7);   padding:0 20px;   border-radius:20px;   box-shadow:15px 15px 10px rgba(0,0,0,0.4); }

注:如果你有兴趣了解更多关于模糊半径,它是如何工作的,它意味着什么,Mozilla 的 David Baron 在他的博客[j.mp/blurradius](http://j.mp/blurradius)<sup>17</sup>上有详细的文章。

你要添加的下一个值是扩散半径,该值越大,阴影扩展得越多。与模糊半径不同,您可以使用负扩散值。如果不包含扩散值,阴影将不会扩散。我们已经将扩散半径值设置为 5px ( 图 11-36 )。

#introduction {   border:5px solid rgba(0,0,0,0.7);   background:rgba(255,255,255,0.7);   padding:0 20px;   border-radius:20px;   box-shadow:15px 15px 10px 5px rgba(0,0,0,0.4); }

偏移、模糊和扩散的值可以是像素或 ems。Opera、Safari、Chrome、Firefox、Internet Explorer 9 都支持box-shadow

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-36。**Opera 10.6 中没有厂商前缀的盒影工作。


17 [dbaron.org/log/20110225-blur-radius](http://dbaron.org/log/20110225-blur-radius)

要查看的最后一个值是inset关键字,它将阴影放置在元素内部。你可以在图 11-37 中看到这一点:由于阴影现在在元素内部,我们已经减小了它的尺寸。

#introduction {   border:5px solid rgba(0,0,0,0.7);   background:rgba(255,255,255,0.7);   padding:0 20px;   border-radius:20px;   box-shadow:3px 3px 3px 2px rgba(0,0,0,0.4) inset; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-37。**Opera 10.6 中使用 inset 关键字的内部框影。

有一个由 Thany 创建的方便的应用([j.mp/thany](http://j.mp/thany)<sup>18</sup>),可以让你在不同的浏览器中查看盒子阴影的渲染差异。您只需检查您希望看到的浏览器并查看示例。目前您可以查看 Firefox 3.6 和 4、Internet Explorer 9、Chrome 10、Safari 5、Opera 11.10、Android 2.2、iOS 4.2 和 Opera Mobile 11。

阴影的乐趣不止于此。你可以有多个阴影,只需用逗号分隔每个阴影(见图 11-38 )。


18

div#introduction {   border:5px solid rgba(0,0,0,0.7);   background:rgba(255,255,255,0.7);   padding:0 20px;   border-radius:20px;   box-shadow:3px 3px 3px 2px rgba(0,0,0,0.4) inset, 15px 15px 10px 5px rgba(0,0,0,0.4); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-38。**Opera 10.6 中的多框阴影

注意:使用太多阴影会影响网站性能。用户滚动时会出现问题:滚动滞后。格兰特·卢卡斯在他的博客上写下了他的发现。这个问题似乎已经在新版本的浏览器中得到解决,但是您应该在一系列浏览器中彻底测试类似的问题。这是安迪·爱丁堡在测试一个网站时发现的,尽管这次border-radius是罪魁祸首。为此,Andy 创建了一个 CSS 压力测试书签,允许您确定性能问题的原因。你可以在安迪的博客([j.mp/cssstresstest](http://j.mp/cssstresstest)<sup>20</sup>)上了解更多关于 CSS 压力测试的内容。


19

20 [andy.edinborough.org/CSS-Stress-Testing-and-Performance-Profiling](http://andy.edinborough.org/CSS-Stress-Testing-and-Performance-Profiling)

最后,如上所述,你也可以使用负偏移值并反转阴影,给人一种来自不同方向的光源的效果(图 11-39 )。

div#introduction {   border:5px solid rgba(0,0,0,0.7);   background:rgba(255,255,255,0.7);   padding:0 20px;   border-radius:20px;   box-shadow:-3px -3px 3px 2px rgba(0,0,0,0.4) inset, -15px -15px 10px 5px rgba(0,0,0,0.4); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-39。**Opera 10.6 中的负框阴影

CSS3 的box-shadow属性有无数的机会。事实上,Viget 的团队写了一篇题为“CSS3 盒影的 39 件荒谬的事情”([j.mp/39shadows](http://j.mp/39shadows)<sup>21</sup>)的文章,其中他们演示了 39 种盒影变体,每种都有一个独特的名称。我们最喜欢的是“软焦点”,当然还有“蝙蝠侠”尼古拉斯·加拉格尔受到作者迪维娅·马年和马特·哈姆的启发,在他的文章“没有图像的 CSS 投影”([shadowmagic](http://shadowmagic)<sup>22</sup>)中,他使用:before:after伪元素来定位阴影,试图创建页面卷曲效果等。确实聪明。


21

22

最终,虽然有一些乐趣,但box-shadow的关键是不要滥用它,巧妙地使用它,当然不要让它看起来像 Photoshop 的默认阴影。

正文-阴影

我们已经看到了box-shadow属性;不出所料,text-shadow惊人地相似。它是 CSS 2.1 的一部分;然而,随着 CSS3 的兴起,它似乎吸引了更多的注意力。您可以使用与box-shadow相同的符号对文本应用一个或多个阴影,即水平偏移、垂直轴偏移、模糊和颜色。请注意,text-shadow没有传播值或inset关键字。

h1 {   color:#777;   text-shadow: 5px 5px 10px rgba(0,0,0,0.5);   /* text-shadow: x offset y offset blur color; */ }

你可以在图 11-40 中看到应用的示例代码。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-40。**Chrome 中的文本阴影

box-shadow一样,你可以对你的元素应用多重阴影。没有inset关键字来帮助我们创建内部阴影。通过思考这个问题并使用多个text-shadow,有些是负值,我们可以实现活版印刷(或嵌入)排版的外观(图 11-41 )。

h1 {   text-shadow: -1px 0 0 rgba(0,0,0,0.5), 0 -1px 0 rgba(0,0,0,0.3), 0 1px 0 rgba(255,255,255,0.5), -1px -2px 0 rgba(0,0,0,0.3); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-41。**使用文本阴影创建的活版印刷

虽然text-shadow是在 CSS 2.1 中引入的,但是 IE 10 中会有。如果你真的需要在 IE 中使用文本阴影,你可以使用微软专有的过滤器来渲染它们。通常情况下,你可以在渐进增强的名义下生活,而不会让 IE 用户看到一两个影子。Opera、Safari、Chrome、Firefox 都支持text-shadow

在我们结束text-shadow之前,我们会给你留一点东西让你思考。为什么不使用text-shadow来创建一些假的立体图,让你的网站在 3D 中真正“流行”(图 11-42 )。下载示例文件来看看这一辉煌的彩色!)?

.anaglyph {   color:rgba(0,0,0,0.8);   text-shadow: 0.1em 0 0 rgba(0,245,244,0.5), -0.05em 0 0 rgba(244,0,0,0.9); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-42。**使用 CSS3 文本阴影的仿 3D 立体图

立体图像很好,但是谁会戴着 3D 眼镜浏览网站呢?我们需要的是真正的 3D,而这正是马克·奥托所做的(图 11-43 )。Mark 的演示在文本上总共使用了 12 个阴影,因此在某些浏览器上可能会有一些性能问题,但它看起来确实很棒。马克在他的博客([j.mp/3dshadow](http://j.mp/3dshadow)<sup>23</sup>)上写了这个实验,我们建议你深入研究一下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-43。**马克·奥托使用 CSS3 制作的 3D 文本text-shadow

对于我们使用text-shadow的最后一个技巧,我们将使用它在文本周围创建一个轮廓。诀窍是在文本的每一边都加上阴影。为了使效果生效,我们必须为文本声明一个与背景颜色相匹配的颜色值来创建透明效果(图 11-44 )。

.title {   color:#ccc;   text-shadow: -1px 0 rgba(0,0,0,0.5), 0 1px rgba(0,0,0,0.5), 1px 0 rgba(0,0,0,0.5), 0 -1px rgba(0,0,0,0.5); }. 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 11-44。 WebKit 浏览器使用多个文本阴影创建轮廓效果


23

如果你的目标受众只使用 WebKit 浏览器(这是不应该的),有一个专有的–webkit-text-stroke属性将达到如图图 11-44 所示的相同效果。不像text-shadow,没有模糊值。它的工作原理如下,但还没有任何规范(关于该属性应该被命名为text-outline还是text-stroke一直存在争议):??

h1 {   color:transparent;   -webkit-text-stroke:rgba(0,0,0,0.5); }

渐变

这里,我们在 CSS3 现象的商业端:渐变。你不再需要创建大量单像素宽的图像来重复你的设计。也许更重要的是,当我们想改变渐变的颜色或长度时,我们不必再回到 Photoshop 或 Fireworks 来编辑这些图形。我们将能够简单地编辑我们的 CSS。

CSS 渐变驻留在 CSS 图像值和替换的内容模块([j.mp/css3images](http://j.mp/css3images)<sup>24</sup>)中,该模块目前处于工作草案中。这意味着这又是一个先有鸡还是先有蛋的问题,或者说是规范与实现的问题。尽管如此,正如我们在本书中所展示的,实现通常是最重要的,所以让我们开始吧。

渐变

基于 CSS 的渐变目前受 Firefox、Safari、Chrome 和 Opera 浏览器支持,并将包含在 Internet Explorer 10 中。它们可以在旧版本的 Internet Explorer 中通过使用过滤器来实现,但是,正如你以前从我们这里听到的,这种方法并不推荐。对于不支持 CSS 渐变的浏览器,请确保指定一种背景色作为备用。

渐变有两种风格:线性和径向。我们将向您展示如何使用这两者。

线性渐变

我们将从引入线性渐变开始。linear-gradient值有效地生成了一个图像,它可以在 CSS 中与图像相同的地方使用,例如background-imageborder-imagelist-style-image属性。之所以这样设计,是因为人们熟悉使用图像进行渐变;因此梯度不能用作color值。基本符号如下所示:

linear-gradient([ [ <angle> | to <side-or-corner> ] ,]?         <color-stop>[, <color-stop>]+  )


24

这些值如下:

  • angle:渐变方向的角度(如 90 度)。您可以使用负值或大于 360 度的值。
  • side-or-corner:定义渐变的起点(如果不使用角度),由四个可用关键字(上、下、左、右)中的两个指定。默认值是左上角,如果只声明了一个值,则第二个值默认为“居中”
  • color-stop:最简单的形式,一个颜色值。沿着梯度的可选停止位置可以作为 0%和 100%之间的值的百分比添加。颜色值可以是关键字、十六进制代码或rgbahsla符号

如果你想到一个在 Photoshop 中应用的渐变,CSS 渐变以同样的方式工作,在从开始(0%)到结束(100%)的不同位置沿着渐变添加颜色停止,如图图 11-45 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-45。**色标示例

要创建从灰色到黑色的垂直渐变,您可以使用:

#introduction {   background:#000; /* fallback for browsers that don’t support gradients */   background:linear-gradient(to bottom, #ccc, #000); }

或者:

#introduction {   background:#000; /* fallback for browsers that don't support gradients */   background:linear-gradient(90deg, #ccc, #000); }

这和写作是一样的

#introduction {   background:#000; /* fallback for browsers that don't support gradients */   background:linear-gradient(#ccc, #000); }

这是因为不需要声明角、边或拐角;默认情况下,渐变是垂直的。你只需要两个颜色值。

我们现在必须承认,我们确实撒了一点谎,说它是我们创建渐变所需的唯一标记,原因是前面提到的浏览器都不支持没有供应商前缀的渐变。因此,为了创建如图 11-46 所示的渐变,我们将添加供应商前缀。

#introduction {   background:#000; /* fallback for browsers that don't support gradients */   background:-ms-linear-gradient(#ccc, #000);   background:-moz-linear-gradient(#ccc, #000);   background:-o-linear-gradient(#ccc, #000);   background:-webkit-linear-gradient(#ccc, #000);   background:linear-gradient(#ccc, #000); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-46。**Firefox 中的垂直线性渐变

你之前已经看到了90deg角度参数意味着渐变是从上到下绘制的。角度值设置从左侧开始的渐变角度,其中

  • 0 度=左侧
  • 90 度=底部
  • 180 度=右
  • 270 度 = 顶部
  • 360 度=完成一整圈后再次向左

你也可以使用负值的梯度,但它们将等同于逆时针方向的正梯度(例如-90 度= 270 度)。为了创建一个从左下角到右上角的渐变(如图 11-47 中的,我们将使用 45 度角。

#introduction {   background:#000;   background:-ms-linear-gradient(45deg, #ccc, #000);   background:-moz-linear-gradient(45deg,#ccc, #000);   background:-o-linear-gradient(45deg, #ccc, #000);   background:-webkit-linear-gradient(45deg, #ccc, #000);   background:linear-gradient(45deg, #ccc, #000); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-47。**Firefox 中的对角线渐变

只需在参数中添加另一个颜色值,即可添加色标。除非您指定一个值来伴随颜色停止,否则渐变会均匀呈现。图 11-48 显示了 50%的颜色停止,但是你也可以使用像素或 ems 来指定停止出现的位置。

#introduction {   background:#000;   background:-ms-linear-gradient(45deg, #ccc, #c8c8c8 50%, #000);   background:-moz-linear-gradient(45deg, #ccc, #c8c8c8 50%, #000);   background:-o-linear-gradient(45deg, #ccc, #c8c8c8 50%, #000);   background:-webkit-linear-gradient(45deg, #ccc, #c8c8c8 50%, #000);   background:linear-gradient(45deg, #ccc, #c8c8c8 50%, #000); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-48。**Firefox 中带色标的对角线渐变

值得花些时间为渐变创建测试用例,看看改变浏览器中的各种值会产生什么影响。

注意:Safari 4 和 Chrome 3-9 版本对 CSS 渐变使用了不同的语法,只指定了一个-webkit-gradient属性。渐变类型(线性或径向)随后出现在第一个参数中。语法基于canvas元素 API 符号。您可以在 WebKit 博客([j.mp/oldwebkitgrads](http://j.mp/oldwebkitgrads)<sup>25</sup>)上了解这种遗留语法。如果您必须在这些旧浏览器中支持渐变,请在现在标准化的linear-gradient值之前添加–webkit-gradient值,以确保新的 WebKit 浏览器使用新的语法,如下所示。

#introduction {   background:#000;   background:-webkit-gradient(linear, 0% 100%, 100% 0%, from(#ccc), to(#000), color-stop(0.5, #c8c8c8));   background:-ms-linear-gradient(45deg, #ccc, #c8c8c8 50%, #000);   background:-moz-linear-gradient(45deg, #ccc, #c8c8c8 50%, #000);   background:-o-linear-gradient(45deg, #ccc, #c8c8c8 50%, #000);   background:-webkit-linear-gradient(45deg, #ccc, #c8c8c8 50%, #000);   background:linear-gradient(45deg, #ccc, #c8c8c8 50%, #000); }


25 [www.webkit.org/blog/175/introducing-css-gradients](http://www.webkit.org/blog/175/introducing-css-gradients)

为了激发你对渐变和可能性的想象,我们建议你去看看由 Lea Verou ( [j.mp/veroupatterns](http://j.mp/veroupatterns)<sup>26</sup>)创建和策划的极具创意的 CSS3 Patterns gallery。Lea 还在一篇优秀的文章中为 24 种方式([j.mp/veroupatterns2](http://j.mp/veroupatterns2)<sup>27</sup>)解释了如何使用渐变创建图案。您也可以将渐变与本章前面提到的多种背景结合起来。你会惊讶于使用 CSS3 渐变所能达到的效果。

径向梯度

径向渐变的语法比线性渐变稍微复杂一些。以下是标准符号:

radial-gradient(   [ [ <shape> || <size> ] [ at <position> ]? , |     at <position>,   ]?   <color-stop> [ , <color-stop> ]+ )

其中:

  • position是渐变的起点,可以用单位(px、em 或百分比)或关键字(左、下等)来指定。使用关键字的方式与background-position相同,默认值是“center”
  • shape指定渐变的形状。它可以是circle(等半径椭圆)或ellipse(轴对齐椭圆)。默认值为椭圆。如果没有声明形状,则从长度单位推断出最终形状。如果是一个长度,形状默认为圆形;如果是两个椭圆。
  • size是渐变结束形状的大小。如果不包含,默认为farthest-side。可以使用单位或关键字设置大小。
    • closest-side定位渐变,使其接触最靠近元素中心的一侧或多侧。如果形状是椭圆,它在水平和垂直方向上与边相交。
    • farthest-sideclosest-side相同,但结束形状基于最远的边。
    • closest-corner定位渐变,使其接触最靠近其中心的元素的一个或多个角。如果形状是椭圆,它在水平和垂直方向上与角相交。
    • farthest-cornerclosest-corner相同,但结束形状基于最远的边。
    • containclosest-side效果一样。
    • coverfarthest-corner.的效果相同
  • color-stop是其最简单形式的一个颜色值。沿着梯度的可选停止位置可以作为 0 % & 100%之间的值的百分比添加。

26 [lea.verou.me/css3patterns](http://lea.verou.me/css3patterns)

27 [24ways.org/2011/css3-patterns-explained](http://24ways.org/2011/css3-patterns-explained)

这一切听起来很混乱,所以让我们进入正题,创造一些梯度。就像线性渐变一样,您需要包含所有供应商前缀。

要绘制一个简单的圆形径向渐变延伸到你的容器的边缘(图 11-49 ),你只需要声明:

#introduction {   background:#000;   background: -moz-radial-gradient(circle closest-side, #ccc, #000);   background: -ms-radial-gradient(circle closest-side, #ccc, #000);   background: -o-radial-gradient(circle closest-side, #ccc, #000);   background: -webkit-radial-gradient(circle closest-side, #ccc, #000);   background: radial-gradient(circle closest-side, #ccc, #000); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-49。**火狐中的圆形径向渐变

尝试将形状和大小值更改为ellipsefarthest-side,看看这有什么影响。

#introduction {   background:#000;   background: -moz-radial-gradient(ellipse farthest-side, #ccc, #000);   background: -ms-radial-gradient(ellipse farthest-side, #ccc, #000);   background: -o-radial-gradient(ellipse farthest-side, #ccc, #000);   background: -webkit-radial-gradient(ellipse farthest-side, #ccc, #000);   background: radial-gradient(ellipse farthest-side, #ccc, #000); }

你可以看到这将你的圆挤压成了一个更大范围的椭圆(图 11-50 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-50。**Firefox 中的椭圆形径向渐变

通过添加位置值,我们可以将渐变移离中心(left top)。我们还将在 200 像素处添加一个额外的色阶(图 11-51 )。

#introduction {   background:#000;   background: -moz-radial-gradient(left top, ellipse farthest-side, #ccc, #75aadb 200px, #000);   background: -ms-radial-gradient(left top, ellipse farthest-side, #ccc, #75aadb 200px, #000);   background: -o-radial-gradient(left top, ellipse farthest-side, #ccc, #75aadb 200px, #000);   background: -webkit-radial-gradient(left top, ellipse farthest-side, #ccc, #75aadb 200px, #000);   background: radial-gradient(left top, ellipse farthest-side, #ccc, #75aadb 200px, #000); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-51。**椭圆形径向渐变在火狐左上角开始

和线性渐变一样,掌握语法的最好方法是尝试一下。给自己设定一些挑战,用渐变再造各种效果;你会惊讶于你用几行 CSS3 就能完成的事情。然而,如果你想更深入一点,约翰·奥尔索普写了一篇关于径向渐变的精彩文章([j.mp/allsoppgrads](http://j.mp/allsoppgrads)<sup>28</sup>),这本书的技术评论员克里斯·米尔斯也写了一篇([j.mp/millsgrads](http://j.mp/millsgrads)<sup>29</sup>)。我们建议你把这些加入你不断增加的阅读清单。

注意:我们包括了传统的 WebKit 语法,以提供最好的支持,但是记住你的优秀 CSS 开发人员承诺 TM 保持你的厂商前缀属性是最新的。一旦您决定放弃对这个旧浏览器的支持,您将不再需要包含这些代码。注意,我们将遗留的 WebKit 语法作为第二个声明,就像我们之前做的那样,所以它会被支持标准语法的最新版本覆盖。


28 [www.webdirections.org/blog/css3-radial-gradients](http://www.webdirections.org/blog/css3-radial-gradients)

29 [dev.opera.com/articles/view/css3-radial-gradients](http://dev.opera.com/articles/view/css3-radial-gradients)

#introduction {   background:#000;   background: -webkit-gradient(radial, 0 0, 20, 0 0, 450, from(#ccc), to(#000), color- stop(50%, #75aadb));   background: -moz-radial-gradient(left top, ellipse farthest-side, #ccc, #75aadb 200px, #000);   background: -ms-radial-gradient(left top, ellipse farthest-side, #ccc, #75aadb 200px, #000);   background: -o-radial-gradient(left top, ellipse farthest-side, #ccc, #75aadb 200px, #000);   background: -webkit-radial-gradient(left top, ellipse farthest-side, #ccc, #75aadb 200px, #000);   background: radial-gradient(left top, ellipse farthest-side, #ccc, #75aadb 200px, #000); }

总之,通过改变值和添加额外的色标,您可以创建圆锥体、光线等。有许多工具可以在创建渐变时帮助你(并使你不必每次都写出多行 CSS)。我们发现最好的是 ColorZilla 的终极 CSS 生成器(图 11-52 ) ( [j.mp/zillagrads](http://j.mp/zillagrads)<sup>30</sup>)。不像其他生成器以不正确的顺序列出声明或者没有更新以反映 WebKit 的语法变化,最终的 CSS 生成器在一个易于使用的界面中拥有您需要的一切。去玩吧。


30 [www.colorzilla.com/gradient-editor](http://www.colorzilla.com/gradient-editor)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 11-52。 ColorZilla 终极 CSS 生成器

重复渐变

如果你想变得更有创意一点,你也可以使用repeating-linear-gradientrepeating-radial-gradient,它们允许我们创建重复的渐变。重复图案(图 11-53 )是使用第一个和第二个色标值之间的差值的倍数创建的。与早期的渐变一样,您需要使用供应商前缀来确保在现代浏览器中获得良好的支持。

div#introduction {   background:#000;   background: -ms-repeating-linear-gradient(#333, #ccc 60px, #333 55px, #ccc 30px);   background: -moz-repeating-linear-gradient(#333, #ccc 60px, #333 55px, #ccc 30px);   background: -o-repeating-linear-gradient(#333, #ccc 60px, #333 55px, #ccc 30px);   background: -webkit-repeating-linear-gradient(#333, #ccc 60px, #333 55px, #ccc 30px);   background: repeating-linear-gradient(#333, #ccc 60px, #333 55px, #ccc 30px); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-53。**铬色中的对角线重复线性渐变

对于径向梯度,我们将使用以下代码(结果见图 11-54 ):

#introduction { background:#000; background: -ms-repeating-radial-gradient(center, 30px 30px, #ccc, #333 50%, #999); background: -moz-repeating-radial-gradient(center, 30px 30px, #ccc, #333 50%, #999); background: -o-repeating-radial-gradient(center, 30px 30px, #ccc, #333 50%, #999); background: -webkit-repeating-radial-gradient(center, 30px 30px, #ccc, #333 50%, #999); background: repeating-radial-gradient(center, 30px 30px, #ccc, #333 50%, #999); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-54。**铬色中的径向重复线性渐变

这里展示的花哨例子中的重复渐变可能不是最漂亮的,但它们确实有它们的用途。

检测支持并帮助其他浏览器

在这一章中,我们已经谈到了浏览器的支持,以及支持或不支持的内容。一般来说,Safari、Chrome、Firefox、Opera 和 Internet Explorer 9 和 10 对这些属性有很好的、广泛的支持,而 Internet Explorer 6-8 则没有。那么对于这些浏览器该怎么办呢?本质上有三个主要选择。

  • 在你的 CSS 中添加回退,以确保功能较弱的浏览器获得合适的体验。
  • 运行一个检测脚本,比如 Modernizr(见第七章),并相应地组织你的样式表。
  • 用 JavaScript 库填补空白,比如在第七章中介绍的 CSS3 Pie。

第一种选择是我们在本章中一直在做的。我们现在将简要解释选项二和选项三。

使用 Modernizr

我们在本书的前面简单地提到了 Modernizr ( [j.mp/modernizr](http://j.mp/modernizr)<sup>31</sup>);现在我们将看看它与我们在本章中看到的 CSS3 属性的关系。

当用户访问您的站点时,Modernizr 运行并检测用户浏览器对 CSS3 和 HTML5 特性的支持,并向html元素添加一系列类。例如,Modernizr 将在 Internet Explorer 中添加一个no-cssgradients类。这非常有用,因为这意味着在一个样式表中可以有两个规则来适应两种浏览器。假设你有一个需要渐变背景的设计,而在那里——你不能退回到纯色。对于 Safari、Chrome、Opera 和 Firefox,您需要设计风格

.cssgradients {   background:-moz-linear-gradient( center bottom,rgb(240,120,14) 50%,rgb(250,151,3) 90%);   background:-webkit-linear-gradient( linear, left bottom, left top, color-stop(0.5, rgb(240,120,14)), color-stop(0.9, rgb(250,151,3))); background: -o-linear-gradient( linear, left bottom, left top, color-stop(0.5, rgb(240,120,14)), color-stop(0.9, rgb(250,151,3))); background: -ms-linear-gradient( linear, left bottom, left top, color-stop(0.5, rgb(240,120,14)), color-stop(0.9, rgb(250,151,3))); background:linear-gradient( linear, left bottom, left top, color-stop(0.5, rgb(240,120,14)), color-stop(0.9, rgb(250,151,3))); }

对于旧版本的 Internet Explorer,您可以使用图像创建渐变,并将属性添加到no-cssgradients类。

.no-cssgradients {   background:#ccc url(img/bg-rpt.png) 0 0 repeat-x; }

使用这种方法不仅意味着那些具有出色 CSS3 支持的浏览器可以获得最佳体验,而且那些支持较少的浏览器仍然可以获得非常好的体验。

CSS3 Pie

你在第七章看到了 CSS3 派([j.mp/css3pie](http://j.mp/css3pie)<sup>32</sup>);让我们在这里使用它来应用一些边界半径到 IE 6,7 和 8。这是我们没有派的规矩:

#introduction {   background:#ccc;   padding:20px;   -moz-border-radius:20px;   border-radius:20px; }


31 [www.modernizr.com](http://www.modernizr.com)

32

要添加对 IE6、7 和 8 的支持,您只需将饼图behavior: url(js/PIE.htc);行添加到您的规则中,然后,您就可以在 Internet Explorer 中获得圆角。

#introduction {   ...   behavior: url(js/PIE.htc); }

CSS3 PIE 涵盖了我们在这一章中学到的大部分内容,所以如果你真的不能忍受 Internet Explorer 中没有圆角,并且能够承受性能损失,或者你不能使用渐进式增强,那么 CSS3 Pie 可能就适合你。

组合 CSS3 效果

您已经了解了 CSS3 中的许多新属性,但是到目前为止,它们都是孤立显示的。现在是时候把它们放在一起了。我们将使用本章中发现的所有属性来设计一个漂亮的提交按钮。我们按钮的基本样式(图 11-55 )如下:

input[type="submit"] {   font-size:18px;   width:auto;   padding:0.5em 2em;   color:#fff;   background:orange; } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-55。**基本按钮样式

首先,转换背景颜色以使用 R = 240、G = 120 和 B = 14rgb值。并使用hsla为边框颜色去除难看边框(图 11-56 )。

input[type="submit"] {   font-size:18px;   width:auto;   padding:0.5em 2em;   color:#fff;   background:rgb(240,120,14);   border:1px solid hsla(30,100%,50%,0.8); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-56。**RGB 和 hsla 风格的纽扣

接下来,通过添加一些border-radius来圆化那些尖角。

input[type="submit"] {   font-size:18px;   width:auto;   padding:0.5em 2em;   color:#fff;   background:rgb(240,120,14);   border:1px solid hsla(20,100%,50%,0.7);   border-radius:5px; }

按钮周围的小阴影将有助于稍微抬起按钮,使其更加明显(图 11-57 )。

input[type="submit"] {   font-size:18px;   width:auto;   padding:0.5em 2em;   color:#fff;   background:rgb(240,120,14);   border:1px solid hsla(20,100%,50%,0.7);   border-radius:5px;   box-shadow:1px 2px 3px rgba(0,0,0,0.5); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-57。**带圆角和外阴影的按钮

现在,应用我们在本章前面使用text-shadow创建的插入文本,使文本看起来好像凹进了按钮。为此,我们给文本添加了四个阴影,每个阴影之间用逗号隔开。

input[type="submit"] {   font-size:18px;   width:auto;   padding:0.5em 2em;   color:#fff;   background:rgb(240,120,14);   border:1px solid hsla(20,100%,50%,0.7);   border-radius:5px;   box-shadow:1px 2px 3px rgba(0,0,0,0.5);   text-shadow: -1px 0 0 rgba(0,0,0,0.3), 0 -1px 0 rgba(0,0,0,0.3), 0 1px 0 rgba(255,255,255,0.5), -1px -1px 0 rgba(250,151,3,0.5); }

为了稍微柔化按钮,我们将为背景使用 CSS 生成的渐变(图 11-58 )。记住这些只能在 Firefox、Safari、Opera 和 Chrome 中使用,所以我们将保留现有的background属性作为后备。现在我们有了:我们完整的 CSS3 风格的按钮!一件美丽的东西!

input[type="submit"] {   font-size:18px;   width:auto;   padding:0.5em 2em;   color:#fff;   background:rgb(240,120,14);   border:1px solid hsla(20,100%,50%,0.7);   border-radius:5px;   box-shadow:1px 2px 3px rgba(0,0,0,0.5);   text-shadow: -1px 0 0 rgba(0,0,0,0.3), 0 -1px 0 rgba(0,0,0,0.3), 0 1px 0 rgba(255,255,255,0.5), -1px -1px 0 rgba(250,151,3,0.5);   background:-moz-linear-gradient( center bottom,rgb(240,120,14) 50%,rgb(250,151,3) 90%);   background:-webkit-linear-gradient( linear, left bottom, left top, color-stop(0.5, rgb(240,120,14)), color-stop(0.9, rgb(250,151,3)));   background:-o-linear-gradient( linear, left bottom, left top, color-stop(0.5, rgb(240,120,14)), color-stop(0.9, rgb(250,151,3)));   background:-ms-linear-gradient( linear, left bottom, left top, color-stop(0.5, rgb(240,120,14)), color-stop(0.9, rgb(250,151,3)));   background:linear-gradient( linear, left bottom, left top, color-stop(0.5, rgb(240,120,14)), color-stop(0.9, rgb(250,151,3))); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 11-58。带有文本阴影和 CSS 渐变背景的按钮

不要停在那里!为:hover:focus状态添加一些样式。结合使用position:relativetop:1px;会产生一个按钮在悬停时被按下的效果。此外,我们已经反转了背景渐变,减少了方框阴影,并移动了文本阴影,以获得两种状态之间所需的对比度(图 11-59 )。

input[type="submit"]:hover, input[type="submit"]:focus {   position:relative;   top:1px;   cursor:pointer;   box-shadow:1px 1px 2px rgba(0,0,0,0.5);   text-shadow: -1px 0 0 rgba(0,0,0,0.3), 0 1px 0 rgba(0,0,0,0.3), 0 0 0 rgba(255,255,255,0.5), -1px 1px 0 rgba(250,151,3,0.5);   background:rgb(250,151,3);   background:-moz-linear-gradient(center bottom, rgb(250,151,3) 50%, rgb(240,120,14) 90%,);   background:-webkit-linear-gradient( linear, left bottom, left top, color-stop(0.5, rgb(250,151,3)), color-stop(0.9, rgb(240,120,14)));   background:-o-linear-gradient( linear, left bottom, left top, color-stop(0.5, rgb(250,151,3)), color-stop(0.9, rgb(240,120,14)));   background:-ms-linear-gradient( linear, left bottom, left top, color-stop(0.5, rgb(250,151,3)), color-stop(0.9, rgb(240,120,14)));   background:linear-gradient( linear, left bottom, left top, color-stop(0.5, rgb(250,151,3)), color-stop(0.9, rgb(240,120,14))); } 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-59。**按钮处于正常和:悬停状态

完整的样式规则可能看起来很深入,但效果很容易实现。当分解成一口大小的块并组合在一起时,您可以使用 CSS3 属性创建漂亮的样式元素。

注意:如果你不记得特定属性的语法,或者不记得哪些需要前缀,有一些网站可以帮助你。Paul Irish 和 Jonathan Neal 的 CSS3 Please ( [css3please.com/](http://css3please.com/))就是这样一个网站。该网站允许您动态编辑规则,并自动为您更新前缀属性。这是一个真正的省时工具,你会发现自己会反复使用它。

拿着奶酪

事情是这样的:您现在已经掌握了所有关于 CSS3 属性的新知识。问题是你将在哪里以及如何应用它们?答案取决于你,但关键是微妙。我们会再说一遍,以确保你记住:关键是微妙。没有什么比 100%的黑色阴影或比例不当的圆角更能说明懒惰了。

不幸的是,我们不会在你每次想添加渐变背景或边框图像时都给你指导。相反,每当你要添加一个很酷的 CSS3 效果时,停下来问自己这些问题:

  • 这有什么用?
  • 它给我的设计增加了什么?
  • 会给我的用户提供更好的体验吗?

如果你不确定或者任何一个问题的答案是否定的,那就不要回答。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

**图 11-60。**西蒙·科利森先生著名的新杂集《colly.com》

如果你不相信我们,试着听听西蒙·科利森(他对网页设计略知一二)。他是这样说在设计他的网站时使用 CSS3 的。

我不得不大胆地去掉一些我多年来用 CSS 做过的最酷的东西,但我真的不后悔。无论如何,这些噱头都有可能降低这个想法的价值。我说,小心使用。

重新设计未被设计的西蒙·科利森

重申一下,以防它还没有被理解,关于 CSS3 属性的两个主要要点是

  • 微妙是关键。
  • 小心使用。

总结

环顾网络,你会发现一些例子,人们使用这些技术只用 CSS 就创造了大量的图标、形状、按钮、背景和标志。有些使用语义 HTML(图 11-73),有些使用许多附加的divspan来实现本质上应该是图像的东西。如果你正在读这本书,你会更清楚。你知道只在适当的时候巧妙地使用 CSS3 属性。

离开如何实现 CSS3 属性或者它们能实现什么,是时候我们开始思考如何使用它们来改进我们的工作流程或者测试实践了。

  • 作为网页设计师,我们需要向客户推销这种渐进式改进吗?
  • 通过使用它,我们是否减少了担心跨浏览器兼容性的时间?
  • 我们是不是花了更多的时间在浏览器中设计,而不是创造无尽的 Photoshop 排版?
  • 这是否意味着我们为客户提供了更物有所值的服务?

我们没有所有的答案,但现在是时候让我们明白并学习如何使用 CSS3 属性,比如本章中的那些属性,可能会在比我们想象的更多的方面帮助我们。我们可以今天使用这些技术,并逐步增强我们的工作,同时确保功能较差的浏览器获得可接受的体验。我们给你的信息很简单:去玩 CSS3 属性,但是记住关键是巧妙地和恰当地使用它们。

作业

至于你的家庭作业,浏览整本书中你一直在做的页面,并在你可以的地方添加 CSS3 属性。小心不要过度。请记住,大多数触摸应该几乎看不到。你应该找到可以增加深度的背景,需要更多启示的按钮,可以使用图形边框的内容部分,需要一些精心制作的阴影的文本,等等。