31. CSS 背景图片

  • 打印

引言

承认吧,读过本课程的第一篇文章后,你一定非常渴望了解如何使你的网站看起来既美观又引人入胜。甚至你可能是直接跳到了这一节,是吗?

背景图像就是用来使你的网站美观迷人的,不过你可能会惊讶于它们与你之前学到的基本概念的联系是多么的紧密。

正如你之前在本教程中了解到的那样,随 CSS 而来的最重要的变化就是将外观独立出来的能力,从语义学方面来说就是某个东西看起来怎么样,或者是它的意义是什么。CSS 背景图像是你可以随意支配的最重要的工具之一,这是因为它使你可以将装饰图片应用到你的 HTML 的特定部分,而无需向你的 HTML 添加任何冗余内容。过去,网页制作者(也就是你!)必须将 img 标签穿插在代码中间,代码间充满了 img 标签。

特别是 background 属性使你的 HTML 脱离了表述混乱。因此,通过现代手段,在网站的建设周期中重新设计和其它转变就可以更加顺利的完成。你可以通过仅仅更改样式表,而非对每个 HTML 页面重新编码,即可对你的整个网站进行更新。这将带来巨大的成本节约,具体数额取决于你的网站的大小。

 

在本文中,我们将会学习到 CSS 背景图像的工作原理,包括通过 CSS 应用背景图像,调整其位置,对其进行水平或垂直铺设,以及使用CSS 图像子画面技术组合背景图像,从而提高网站性能

本文结构如下:

它是怎样工作的?

用来控制背景的 CSS 分成了若干不同的属性。使用 positioncolor 之类的属性,你就可以着手控制你的页面的感官效果。在本文中,你将全面了解 CSS 背景图像,并逐步建立一个警报对话框。

首先我们来进一步了解一下可供我们使用的各种属性。

背景属性

属性定义描述
background-color 设置 HTML 元素的背景颜色

有多种方式可以用来指示 background-color,包括 RGB 值和关键字。大多数人使用十六进制符号——一个井号 (#),后跟六个字符。#RRGGBB:前两个字符表示红色水平,第二对以及最后两个字符分别表示绿色和蓝色水平。

许多颜色采集工具可帮助你找到特定颜色的十六进制符号。例如,纯红是 #FF0000。

Photoshop colour picker will give you the hex value of your colour

有效值包括 color 值、transparentinherit

image 指示背景图像的路径或 URL。

通过使用 URL 告知浏览器图像的位置来设置 background-image。例如:url(alert.png)。注意,路径以关键字 url 开头并带有圆括号。这种语法很重要,因为这样浏览器才能明白你是在指定一个位置。

有效值包括 URLnoneinherit

repeat 指示背景图像平铺的方向。

图像可以垂直平铺、水平平铺,或者既有垂直又有水平方向的平铺,来占满 HTML 元素的全部高度和宽度。使用 background-repeat 可指示浏览器对一个背景图片进行平铺。

有效值包括:repeatrepeat-xrepeat-yno-repeat

attachment 设置用户滚动页面时背景图像的行为。

图像既可以随内容滚动,也可以固定在显示屏幕上。有效值包括 scrollfixedinherit

position 告知浏览器背景图像的位置。

图片可以在其应用到 HTML 元素的边界内任何位置显示。使用 background-position 可将图像放置在恰当的位置,以实现视觉效果和层次感。

有多种方式可以表示背景定位,比如关键字和数值。关键字(如 topbottom)非常管用而且易于阅读。像素值非常精确,但不适用于更改高度和宽度。使用 CSS 图像子画面技术时,负像素值很有用,这点稍后你就会了解到。

尽管像素和百分比值定位图像的作用方式差异很大,但是使用像素和百分比值时,起点始终是 HTML 元素的左上角。不论图片和容器的大小如何,用像素来定位图像时总是将图像向容器的底部和右侧(或如果是负数值,则向顶部和左侧)移动设定的像素值。而用百分比值来定位图像时则是按照容器大小和图像大小之间差额的百分数来移动。如果容器和图像一样大,这种方式将无法移动图像。

有效值包括length(通常单位是像素),percentage(元素宽度的百分数),以及关键字toprightbottomleftcenter。注意,中心可以指水平中心或垂直中心。另外注意,你可以将百分比和像素结合使用,但关键字和像素或关键字和百分数不能结合使用。

background 一种缩写属性,可用于在一行代码中描述所有其它属性的。

缩写属性确实很好用。许多开发人员使用缩写属性使 CSS 尽可能精简,并集合所有有关联的属性。你可以使用缩写来编写一个一般规则,然后在需要的时候用某个特定属性将其覆盖。

所有属性必须以一致的顺序表示,以使浏览器可以轻松解读你想要的样式:

  1. color
  2. url
  3. repeat
  4. attachment (very rarely used; may be omitted)
  5. horizontal-position
  6. vertical-position

用到所有属性的缩写(attachment 除外)示例如下:

background: green url(logo.gif) no-repeat left top;

创建警报对话框

现在有关的基本概念已经介绍完了,下面我将带你建立一个完整的警报框实例,该实例将涉及背景图像的所有方面。

设计

我们假设一个平面设计师已提供了一个你要为你的网站创建的警报对话框的可视模板。看看这个警报,你看到的背景是浅橙色的,在周围的段落中很鲜明。左上角还有一个 10 像素的警报图标。

注意,这个模型有一行文本,但是以后可能会包含更多文本。web 开发员的一项最重要的技能就是,可以预见一项设计在未来会如何演变。在对网站给人的视觉上的艺术感受的考虑中,有一部分就是关注从开始设计到重新设计的连贯性。因此警报对话框可能包含一行以上的文本,甚至多个段落、列表或其它 HTML 元素。你应当尽量努力做一个元素不可知论者——尽可能相信网站以后会有很多目前不可知的变化。这将增加代码再利用的可能性,并使网站尽可能高效。模型如图 1 所示。

final mock up

图 1:平面设计师所提供的我们的警报框模板。

平面设计师还提供了我们要用的图标,如图 2 所示。

alert icon

图 2: 警告图标。

代码

根据你在本文第一部分所了解到的 CSS 背景的相关内容,你可能已经在思考如何建立这种警报对话框。我希望你现在就开始尝试,然后把你的成果和我的示例作个比较。

好的,试过了吗?现在我们来逐步讲解一下。每个屏幕截图都链接到了代码示例上,因此你可以找到每一部分的源代码。用代码来进行试验,试着增加或减少属性值,或者尝试替换某个属性。你可能想要跟踪每一步的效果,可以在 Opera Dragonfly 或 Firebug 之类的工具中写下每行新代码,这样你将可以立即看到每一步的结果。

创建 CSS 钩子或选择符。

首先你需要创建一个 alert 类,以供 CSS 追踪。创建新的 CSS 和 HTML 框架文档,将 CSS 链接到 HTML 文档并将以下代码添加到这两个文件中:

CSS:

.alert { ... }

HTML:

<p class="alert">
  <strong>Alert!</strong> 此处是警报对话框文本。

</p>

在这里,我采用 class 来设计警报,而非 id,这是因为页面中可能有一个以上的警报,例如带有多个错误的表单元素。在建立 HTML 时,你应该使你的 CSS 尽可能灵活,并使所有元素都与设计一致。

好了,你已创建了一个稳妥的基础,但由于你尚未添加任何修饰,因此看还是像普通段落易于。下面我们就来做这一步。

注意:我特意选择不限制 alert 类的段落;这样就可以方便地让警报框包含其它元素。你应当使你的 CSS 尽可能地灵活。

添加背景颜色

在第 29 章用 CSS 来样式化文本中你已经学会了将背景颜色用在文本处理中。同样的概念适用于任何 HTML 元素并且可与背景图像结合来创建视觉效果。如果背景颜色既没有被设定,也没有继承其它的设置,将默认为透明。

我们将橙色背景颜色添加至警报框,使其从周围的本文中凸显出来。保持文本和背景颜色的对比度的合理水平是很重要的,因而你不会希望颜色太暗。添加以下属性到 CSS 规则内。

.alert{background-color: #FFFFCC;}

警报框现在应当如图 3 所示。

Code

图 3:添加了背景颜色的警报框。

应用背景图像

现在让我们将图像添加至这个警报。背景图像的路径必须加 url(),如下面的代码所示。将下面高亮的代码行添加至 CSS 规则中。

.alert{
  background-color: #FFFFCC;
  background-image: url(alert.png);
}

现在,警报框将如图 4 所示。

code with background image

图 4:已添加背景图像,但铺设效果看上去不好。

记住,每个背景属性都有一个默认值——如果你未指定属性值,将应用默认值。当然你会发现该图像平铺在了我们的整个警报上,很像是厨房地板上的镶嵌瓷砖。为什么不去掉这个呢?背景图像默认设为水平和垂直平铺。平铺背景对于占满屏幕或特定 HTML 元素的渐变和花纹特别有用,不过此例不需要实现这个效果。

控制背景再现

Repeat horizontally and vertically

图 5:与我们的背景图像非常相似,这些瓷砖向水平和垂直两个方向平铺。

读规范的确很吓人,但在你钻研无数的浏览器的差异之前,规范真的是一个好去处,可以让你了解 CSS 应有的效果。请看一下 W3C 规范的颜色和背景部分,找出当你不想让某一背景图像平铺时应该使用的关键字。我们将在下面的例子中用到它。

找到了吗?注意,在该规范中有一章内容涵盖了每个背景属性,包括background-repeat。在Value下,你将看到所有可能的选择,包括:repeatrepeat-xrepeat-yno-repeatinherit。默认情况下(最初设置)背景图像设为平铺。不指定方向,是指图像既有水平平铺,又有垂直平铺。你很可能猜测 no-repeat 就是你要找的防止图像在两个方向上平铺的值。将以下高亮代码添加至 CSS 规则。

.alert{
  background-color: #FFFFCC;
  background-image: url(alert.png);
  background-repeat: no-repeat;
}

警报框现在如图 6 所示。

Code for Step 4 background repeat

图 6:警报框带有一个背景图片(无铺设)。

另外,你可以选择在两种方向上平铺(就像厨房瓷砖那样),或者两种方向上都没有平铺。渐变通常用水平或垂直平铺(参见图 7)。你不必知道 HTML 元素的大小,只需从渐变图像上切下一片,将其设置为在你想要的方向上平铺——x 轴水平,y 轴垂直两种方向。花纹通常在两种方向上平铺,而图标通常不平铺。在稍后的示例中,你将进一步了解 background-repeat

repeat-x example

图 7: 此例中的黄绿色瓷砖仅在水平方向上平铺。

我们来看一个我的网站中的实例——请看图 8。

A tiny image is tiled horizontally to create a three colour design across the top of my website.

图 8:我自己的网站中的一个平铺实例。

我用于添加此装饰效果的 CSS 相对简单。我使用repeat-x使背景水平平铺:

body{background-repeat: repeat-x}

固定

attachment 使你可以指定用户滚动页面时背景的工作方式。默认行为是 scroll,它使背景图像随内容滚动。

而将 background-attachment 设为 fixed 则使元素固定在浏览器窗口,因此当背景图像固定到的元素内的内容滚动时,背景图像会保持不动。这会带来奇怪的效果,这一效果仅当你在其固定到的 HTML 元素上滚动鼠标时可以看到。W3C 用它标注其规范的状态,例如左上方的“W3C 候选推荐标准”图片。滚动页面,图像还是位于左上方。图像被固定至 body 元素,因而总是可见的。

这一步对我们的演示不起什么作用,因为默认情况下浏览器将背景图像设定成了滚动,但我们还是要将其添加至代码以便你可以看到该属性的使用方式。将高亮代码添加至 CSS 规则:

.alert{
  background-color: #FFFFCC;
  background-image: url(alert.png);
  background-repeat: no-repeat;
  background-attachment: scroll;
}

如图 9 所示,警报框的显示与之前没有太大差别。

Code for background attachment

图 9:没有太大差别。

对图像进行定位

定位是一种精细调整,使你可以精确地将背景图像水平和垂直地放在你想要的位置。这一属性采用 topcenterright100%-10%50px-30em 等关键字和数值.

图 10 显示的是一些属性值,当你要将你的背景图像放置在不同位置上的时候就会用到这些值。

Examples of possible background positions

图 10:各种使用关键字、百分数和像素的背景定位示例。

下面我们来定位背景图像。你想让其位于左上方,但不碰到边缘,因此你需要将其从顶部和左侧偏移 10 个像素,这可通过向 CSS 规则添加以下高亮代码来实现。现在你也做一下。

.alert{
  background-color: #FFFFCC;
  background-image: url(alert.png);
  background-repeat: no-repeat;
  background-attachment: scroll;
  background-position: 10px 10px;
}

第一个值是水平偏移量,第二个是垂直偏移量。在此例中,他们是相同的。现在,你的警报框应如图 11 所示。

Code with background position

图 11:使用定位功能放置背景图像。

提示:要么用关键字要么用数值——如果你同时使用两者,老式浏览器可能会忽略你的声明。使用关键字 rightbottom 效果相同 —— 分别是水平或垂直移动 100%

像专业人员那样使用缩写集中表述

正如你所知道的,某些 CSS 属性可以组合在一起。Background 以及其所有子属性都包含在其中。迄今为止,我们编写的 CSS 代码缩写形式如下所示:

.alert{background: #FFFFCC url(alert.png) no-repeat scroll 10px 10px;}

提示:在组合 background 的子属性时,通常将这些属性按照以下顺序书写(这对跨浏览器的兼容性以及样式表的组织和维护都很重要):

  1. color
  2. image
  3. repeat
  4. attachment
  5. horizontal position
  6. vertical position

用上面的缩写重置以前的 CSS 代码,你会看到如图12所示的结果:

Finished product

图 12:缩写效果立竿见影!

用代码来做试验

记住 CSS 所有细微差别的最好途径就是亲手尝试——改变示例中的一些属性,然后看一下效果。将 background-position 设置为 100% 100%,然后你会注意到所得到的效果与使用关键字 rightbottom 的效果是相同的。那么如果将它改变为 -5px 0 又是什么效果呢?你觉得为什么会看不到完整的图片了呢?

质量测试

测试对于提供更好的用户体验来讲是很重要的。由于具体配置的差异,即使网站在你的电脑上看起来效果很好,也并不意味着在每个人的电脑上都有同样的效果。测试警示框的时候,你应该遵循以下几条最基本的步骤:

  • 增加或者减少框内的文字量
  • 在你的浏览器里增加文字大小至少两个字号。用 ems 定位图片是不是看其来效果要好?然后,当你增加文字大小的时候发生了什么?
  • 在其它元素里应用这个 class 警示,如 divpulstrongem。你需要改变哪些地方才能不必专门使用 class
  • div 警示中包含若干段落和一个列表——会依然有效吗?
  • 确认警示在一级浏览器(也称为 A 级)上可见。我的建议是在好的浏览器上编码,一旦有效就在 Internet Explorer 应用。

严格的测试是学习编写 CSS 的一部分,学习越认真,你就掌握的越快

Sprites(子画面)

用户们都会苛求完美。他们希望你的网站是吸引人的,是交互式的,并且希望浏览速度要快,当然,在某种程度上包含大量 CSS 背景图片会大大减慢你的网速,你发出的 HTTP 请求越多,你的网站速度就会越慢(HTTP 请求是指当你的网站连接到某个网站上并要求服务器端将该网站的其它资源发送过来——例如一个 CSS 文件或者图片时,每一个额外的请求就意味着该网站更长的加载时间)。要解决这个限制,你可以将相关图标结合到一张图片上,即众所周知的CSS 图像子画面技术background-position 属性允许你将图片放置到合适的位置,以便图标通过应用了 CSS 图像子画面技术的 HTML 元素的窗口显示出来。

从图 13 可以看出,为了在 HTML 窗口显示地球图标,可以用 left top 放置图片。为了移动图片位置使警示图标显式出来,背景图片位置需要改为 -80px 0。水平方向的负值可以把图片拉到左侧。

Only the part of the background image which is inside the HTML element is visible

图13:使用 CSS 图像子画面技术减少 HTTP 请求

注意:如果你使用负背景定位值,就算你指定了 no-repeat 命令,Safari 也会平铺你的图片。这一点在你开始用背景图片创建更复杂布局的时候就要记住。

复杂的子画面及背景图片示例

我们来看一下怎么利用 CSS 图像子画面技术来取得更好的效果。假如我们的平面设计师传给我们一个新的模板,这个模板是一个博客主页上的链接列表,链接到博主的 LinkedIn 资料、RSS 文件、照片以及书签等内容。看一下每个链接,我们看到链接是从图片中间的白色过渡到顶部和底部的灰色,而更复杂的是,设计者要求访客的鼠标悬停在上面的时候可以变成没有颜色变化曲线的纯白色,如图 14 所示:

List mockup

图14:新设计模板

标识中应通过 img 元素来包括 Logo,尽管如此,使用 CSS 图像子画面技术仍然是一个使子画面下载更快的好办法,这样会使下载速度像只有一张图片那样快(而非 4 张),并且它简化了你的 HTML,减少了需要的标记数量。

创建子画面

首先的步骤就是剪切 4 个 logo 然后创建子画面集,如图 15 所示:

logos sprite

图15:子画面集

你同时也需要剪切 1px 宽的渐变切片。为了让大家看清楚,我剪切的稍微大一点,但是你只需剪切 1px 大小就可以。如图 16:

gradient bkg

图 16 渐变背景切片

该列表的 HTML 是一个包含了链接的无序列表,注意链接里的空的 span 元素,不要事先就固定包含文本的元素的 heightwidth,这很重要 —— 毕竟你并不知道文本到底会有多大。如果文本翻译成德语会怎样?你可以使用额外的 span 来显示这些 logo。你可能不想用额外的非语义标记来显示 logo,因为那样会使你的 HTML 看起来很杂乱。这种情况下需要使用一个大的子画面并且在图标之间保留空白。但是要知道这样会使网速慢的用户的链接速度更慢,特别是使用手机上网的用户。列表的代码如下 —— 将其添加到 HTML 模板中:

<ul class="navigation">
  <li id="resume">
    <a href="#"><span></span>Resume</a>
  </li>
  <li id="rss">

    <a href="#"><span></span>RSS Feed</a>
  </li>
  <li id="photos">
    <a href="#"><span></span>Photos</a>

  </li>
<li id="links"> <a href="#"><span></span>Links</a> </li> </ul>

CSS 综合利用这两种背景图片。首先,看一下背景图层的图片,有三个有趣的现象值得注意:

  1. 首先是图片在水平方向的平铺(repeat-x)。这也是为什么我们可以使那么小的图片散布到整个列表的原因。
  2. 其次是图片在垂直方向上的居中。你想让突出的白色部分出现在列表的中间位置,因此应该将背景定位设为 left center
  3. 1. 最后一点,在 CSS 中我应用了与渐变图片的灰色部分相同的背景色,这样,即使元素增大,也不会破坏整体效果。要了解更多这方面的技巧,我建议大家读读 Dan Cederholm 的 Bulletproof Web Design 这本书。

添加以下 CSS 到一个新的 CSS 文件,然后将其链接到 HTML 文件中:

.navigation, .navigation li {
  margin:0; 
  padding:0;
}

.navigation li {
  border-top: 1px solid white;
  list-style-type:none
}

.navigation li a {
  background: #E2E2E2 url(sprite_gradient_bkg.jpg) repeat-x left center; 
  padding:20px; 
  display:block;
  font-family: Arial, Helvetica, sans-serif;
  color:#333; 
  font-size:18px; 
  text-decoration:none
}

/* hover effects */

.navigation li a:hover, .navigation li a:focus{
  background: transparent none;

}

最后一行意味着当用户通过鼠标悬停其上或者通过键盘对其聚焦的时候元素应无背景图片或者背景色。也许你想知道为什么我用了背景属性而非列表项?答案是 Internet Explorer 6 及其以前的版本在非链接元素上并不支持像hover这样的伪类。我的目的是使它适应这个限制。

下一步你可以为那些小 logo 创建 CSS 了。像往常一样,你可以从为导航模块里所有的 span 元素定义最常见的情况开始。这里你可以定义图片为所有 span、所有平铺和背景位置可用(每个都不一样,因此我们只说明第一个),你可以为其使用缩写。注意我用简短的语言来使用 CSS 命令将代码划分段。将下列代码添加到 CSS 文档的底部。

/* general case */

.navigation span {
  background:url(sprite_logo.gif) no-repeat left top;

  height:15px;
  width: 15px; 
  margin-right:20px;
  display:-moz-inline-box; 
  display:inline-block;
  vertical-align: middle;
}

能够驾驭最普通的情况之后,你现在就可以定义例外的情况,或者是定义每一个 logo 与其它 logo 的差异了。在本例中,需要做的 CSS 代码变更仅仅只是 background-position。每一个列表项都需要将图片向左拉至少 15px,因为,每个 logo 都有 15px 的宽度。将以下代码添加到 CSS 文件的末尾:

/* exceptions */

#rss span {
  background-position: -15px 0;
}

#photos span {
  background-position: -30px 0;

}

#links span {
  background-position: -45px 0;
}

这个例子最开始看上去有点吓人。将你的注意力保持在背景图像上。在本例中,我用负的像素值来向左拉背景图片,以使图片相关部分可见。正值推动背景图片向下和向右,负值则拉动图片向上和向左。

已完成的示例里调整 background position 值,这样就可以更好地理解如何调整子画面的位置。

总结

现在你应该已经掌握了 CSS 背景图像,此外,你已经可以更加自如地阅读规范,这样如果你对某个属性还有所怀疑的话,就可以自行查找了。本文涵盖了背景颜色、背景图片、背景平铺、背景固定以及背景位置。你也了解了开发人员为何使用 CSS 图像子画面技术,以及怎么使用这门高级的技能。

图片来源

练习题

  • 一个段落大小为 40*80px,而你的背景图片是 60*200px,你会看到整张图片还是部分图片?为什么?
  • 如果你想把图片放置在 blockquote 元素的左下角,请填写正确的数值

    blockquote{background: yellow url(quote.png) no-repeat scroll ____ ____ ;}
  • 如果你想在文档中每一个具有 “question” 类的 h2 元素应用渐变图案,你是否会用 repeat-xrepeat-yno-repeatrepeat 来达到类似于下面示例中的效果?为什么?

    Example Heading

  • 在第三个问题中,示例中的背景位置是什么?你如何创造性地使用背景色来保证背景可以扩展到任何高度?为什么这个很重要?
  • 你可以用那些缩写来移除所有背景属性?
  • CSS 图像子画面技术的目的是什么?

延伸阅读