网页设计杂谈(16)——CSS设计中的 Sprite 技术
如何在CSS中使用图像,是令不少初学者琢磨不定的问题,往往会使人感到有些迷茫。
今天专门就这个问题来谈一谈CSS Sprite技术,这是个非常实用的技术,在我们的几本CSS书籍中,都没有深入介绍。今天算是做个补充。
从十年前说起
十年前,网页设计开始逐渐成为一项应用比较比较广的技术,那时制作网页就开始“切图”了。之所以要切图,主要有两个目的:
1:为了使用表格布局,就要把图像切成一个个小部分,分别放到表格中各自的单元格里面。
2:这样做可以使网页打开和显示速度更快。这是为什么呢?原因是,那时候人们主要还是通过33.6K或者54K的电话线拨号上网,速度非常慢,比现在主流的上网速度慢10到40倍,所以把一个比较大的图像分成若干块,这样浏览器在显示的时候 ,就会同时开多个线程,同时下载各个小块,这样可以更充分地利用带宽,其实原理就和“FlashGet快车”等下载软件是一个道理。
十年后又如何?
当今世界上没有什么技术的发展速度,可以和IT技术相比的。十年后的今天,情况已经发生了很大的变化,很重要的一点是上网的速度快了很多,虽然我们还不能和发达国家(甚至我们不甚看得上的韩国)动辄上百兆的入户带宽相比,但是好歹1-2兆的ADSL还是很普及的。当下载速度快了以后,我们考虑的侧重点就不一样了。
1:当浏览器显示一个图像时,所花费的时间实际上由两个部分组成的,通俗来说是“发出请求建立连接的时间”以及“传输图像数据”的时间。在网速很低的时代,前者时间与后者相比可以忽略不计,而当宽带上网以后,后者的时间大幅度的降低了,而前者并没有明显降低,因此前者所占的比例就不能忽略不计了。
2:一个网页上往往需要很多边边角角的很多小图象,比如按钮、圆角、边框等等,这写图像通常本身的大小都非常小,因此他们的传输时间都非常短,反而建立连接的时间无论图像大小,都是一样的,因此“建立连接”花去了整个下载时间中的较大比例。
3:因此,人们就想到了一个方法,把这些小图像都平放在一个大图像中,这样当显示页面的时候,一次就把他们都下载下来了,然后通过CSS仅仅把需要的部分显示在需要的位置,本质上的原理就是“通过减少HTTP请求的次数,达到加快网页打开的速度的目的。”
4:
读者可能要问,“Sprite”是什么意思?这个技术为什么要叫这个名字呢?说到这里,就要再往前推若干年啦,想当年,如果你玩过任天堂的红白机,肯定会知道超级马力、魂斗罗之类的经典游戏,90后的新生代朋友估计就未必知道了,我们这个年纪的人应该是没有人不知道的,总之就是那种很古老的接在电视上的游戏了。而“Sprite”就是这些游戏程序开发中的一个很重要的技术,就拿超级马力来说吧,超级马力这个人物、他要吃的蘑菇、花、金币、要顶的砖块、要躲避的小怪物、乌龟等等游戏中的各种元素,都是事先做好的一些图像元素,这些元素的大小都是固定的,然后整个游戏就是把这些元素拼接在画面中形成的。而所有这些基本的图像元素就叫做Sprite——“精灵”。
5:和上面说的当年开发游戏中的Sprite很类似,如果我们把需要显示在页面中的多个图像放到一个图像中,一次性下载到浏览器,然后再分别显示到需要的地方,拼接成最终的效果,因此就使用了Sprite这个名词了。
案例说明
下面通过从小到大的几个例子,说明下Sprite技术是如何应用在实际工作中的。
实际案例1:
在《CSS设计彻底研究》这本书里,我们虽然没有给出CSS Sprite这个名称,但实际上也介绍了使用的方法,192页,8.4节“三状态玻璃效果菜单”这个案例中,我们就是把三种状态的背景图像都放在了一个图像文件中,并提到了这样做的两个优点:
1:减少了文件的数量,便于网站的维护管理。
2:鼠标指针移动到某个菜单项上,如果要更换一个背景图像文件,那么有可能要替换的图像还没有下载下来,就会出现一个停顿,浏览者会不知发生了什么,而如果使用同一个文件,就不会出现这个问题了。
这个完整案例比较复杂,这里应用的CSS Sprite只是整个例子中很小的一部分,这里就不再详细介绍了。下面针对Sprite举一个实际的案例。

实际案例2:
其实我们这个网站的页面右侧栏中,就用到了Sprite技术。如果您使用Firefox浏览器浏览本页面,用鼠标右键单击右侧栏的每个圆角框中的四字标题,比如“视频教程”这4个字,然后在弹出菜单中选择“查看背景图像”,你将会看到如右图所示的这个图像。
可以看到,我们把若干个项目的标题都放在了一幅图像中。在对应的CSS中,比如“视频教程”这4个字所在的元素是一个span,它的CSS代码如下,文件style.css 第 803 行:
1 2 3 4 5 6 7 | #sidebar ul li h2 span.category { background: url(images/side-title.png) no-repeat 0 -40px; display:block; height:20px; width:200px; } |
可以看到,这个图像作为span元素的背景,span元素设置为块级元素(相当于div),并设置高度和宽度,在background属性中,设置了图像的路径,以及位置,关键在于这里的-40px,表示向上移动40像素,这时在高20px、宽200px这个“窗口”中显示的就正好是“视频教程”这一行了。其他各标题,以此类推,只要修改这个竖直方向的数值即可了。
这个小例子非常简单,相信只要有一点点CSS基础的读者都可以一眼就看明白。如果对上面这几行代码还不清楚的读者,可以看一下右侧“视频教程”目录下的教程,相信就会理解了。
下面我们看看一些大网站是怎么用这个技术的。
Apple公司网站
苹果公司是彻底靠设计吃饭的公司,我们先来看看苹果公司网站的菜单是如何实现的,请进入苹果公司的网站: www.apple.com.cn ,然后使用上面相同的方法,查看背景图像,可以开到结果如下所示。或直接察看源文件,也许以后苹果公司网站会改版,这个图像可能会变化。

原来是把菜单的不同鼠标状态都做到了一幅图中,再根据不同的页面,以及不同的鼠标状态,通过CSS在各个菜单项对应的“小窗口”中透出需要的那一小块。
淘宝网
淘宝网站的设计是很重视用户体验的,也是不少设计师向往去工作的公司。我们来看看淘宝是否使用了Sprite技术,结果如下图所示,点击查看源文件。
可以看到,同样,也把页面上的很多边边角角的设计元素都做到一张图上,然后再拼成所需要的显示效果。
思考题
1:Sprite技术的核心原理是什么?你能否将淘宝中Sprite图的各个“零件”与最终页面中出现的位置和元素对应起来?
2:从Sprite这个技术来由,你能否体会到“新技术”和“老技术”之间的关系?对你学习新技术有什么启示吗?
3:自己动手,查看一下其它还有那些大网站使用了类似的技术,163.com、yahoo.com、amazon.com 。
6,015


Thanks , I鈥檝e recently been searching for information approximately this topic for a while and yours is the best I have found out till now. But, what concerning the conclusion? Are you positive concerning the supply?
请问您能看得出什么意思么,如果看不出请通过如何,不要翻译拉!
Being a fellow blog author I am fully aware that it鈥檚 extremely difficult to come up with interesting blog post ideas time after time.My site:Review Scam
Pretty good post. I just stumbled upon your blog and wanted to say that I have really enyed reading your blog posts. Any way I鈥檒l be subscribing to your feed and I hope you post again soon
怎么才能准确定位的把每个小图片整合到一张图片上。有什么好的方法指导下
还是没太明白是原理,图片的最初显示位置是从哪的呢,它又是以哪个位置为原点进行定位的呢。
几乎大网站都是把背景图片做到一张图上 , 国内用户体验方面我比较欣赏腾讯系和阿里系
zlzlcl ,
是的,这是一个非常常用的技术了,其实也很简单。
欢迎常来这里交流!
“把页面上的很多边边角角的设计元素都做到一张图上”
引用时,通过调整背景图像的位置来实现。这样一张图的大小就增加了?
呵呵,早就注意到这个问题,114la的几个页面是这样的,学到了,谢谢!
原因是,那时候人们主要还是通过33.6K或者54K的电话线拨号上网,速度非常慢,比现在主流的上网速度慢10到40倍,所以把一个比较大的图像分成若干块,这样浏览器在显示的时候 ,就会同时开多个线程.
我被你的 多个线程这几个字震慑了,哈哈,人才,害人啊
苹果那个设计有一个问题,如果下面链接一个DIV,有可能会出现重复的情况。这是指技术不好的人,比如我。我在SAFARI下面做的网页很正常。到了IE就是一塌糊涂。
nabate ,
就目前的浏览器状况,做CSS的设计,浏览器兼容性是个大问题,需要不断地积累经验,遇到的问题多了,慢慢就有经验了。
报告一个笔误:苹果的那张图,鼠标放上去显示的是“taobao-sprite”…
Betty,
多谢指正,已经改过来啦!欢迎常来这里交流!
这个sprite得确弥补了“请求连接时间的数量呀” 以前在《CSS设计彻底研究》这本书中看到过那个在:hover上运用的sprite,一开始不理解搞不懂温老师为什么要这么做,后来书中也讲解了为了快速显示!
但是还是没有彻底明白,今天算是彻底明白啦!!哈哈!
口水一下,我大约是在去年7月份的时候开始接触CSS 这个词 ,一开始在网络上搜索的视频,第一个看的视频是曹鹏老师的CSS教程,说心里话曹鹏老师的教程并不适合新手,看了几十课也就只得到几十个CSS 单词!后来在某天发现 《精通CSS+DIV》这个书, 心里想都没想就买了。一看哇塞 ,CSS的葵花宝典哦!超赞。 每一个例子讲的知根知底,让我彻底明白其中的代码含义和意思! 一开始学完了《精通CSS+DIV》这本书感觉自己的CSS技术还行吧, 后来买了《CSS彻底研究》这本书才发现俺还是个菜鸟 !在《精通CSS+DIV》这本书中每一个例子我都亲手做了一边, 最难的例子莫过于书中的三个用JS随机显示的三个BLOG!但是到了《CSS设计彻底研究》这本书中我发现那三个例子是最简单的, 所以希望和我一样只看过《精通CSS+DIV》的朋友一定不要忘记再来本 《CSS彻底研究》,这个书是温老师的经验和结晶。里面大量的阐述了外国牛人设计师的设计理念和一些超牛的技巧,就和sprite一样 ,不看不知道,一看吓一跳!! 目前我正在研究 希望一起进步的朋友给我留言哦!HOHO! :D
小渔 ,
谢谢你的经验!很好的学习体验,加油!
好象jS()这个单词给屏蔽了呀!
小渔 ,
是的,等有时间我查一下源代码,调整一下。
哈哈,这就是老师在 http://learning.artech.cn/20081111.css-slide-skill.html 这里说的“有时间”吧……
anyLiv ,
果然啊~~俺这一个”有时间”,就推出去半年了~~~:P
另,补充一个 g.cn 的例子:
http://www.google.cn/intl/zh-CN/images/toolbar_animation_20090316.png
anyLiv,
你这个例子举得不错,这个还用到了JS了。
Sprite 用的越来越多了,确实能很大程度的提高速度。
“超级马力”?不是“超级玛丽”吗?
青色,
是的,拼音输入法嘛:)
不过严格来说叫“超级玛丽”其实不对,那个Mario明明是个男的吗,咋能搞个女名,应该翻译为“超级马里奥”~~~
青色兄好搞笑 我师傅更搞笑 你怎么知道人家是男的 你没看过《超级学习霸王》这部电影吗?
里面的超级马力 就是用女的哦 :D 哈哈!!!
小渔,
这就是年龄代沟阿~~~
Mario是一个穿工作服的水管工,有胡子,它的最终目的就是要解救公主MM~~~