什么是css Sprite?或许你不知道它,但是你正在用这种技术。本文从CSS Sprite含义、相关技术、示例、优化技巧介绍优化工具等方面对此做了下全面的总结,通过本文相信你会对CSS Sprite有一个基本的了解和认识。
一、关于CSS Sprite
什么是Sprite?
“Sprite”(精灵)这个词在计算机图形学中有它独特的定义,由于游戏、视频等画质越来越高,必须有一种技术可以智能的处理材质和贴图,并且要 同时保持画面流畅。“Sprite”就是这样一种技术,它将许多图片组合到一个网格上,然后通过程序将每个网格的内容定位到画面上。
Sprite被定位到一副静态图片上,并且通过简单的程序或硬件即可正确定位到画面上,一幅幅图片就像是被“变”出来的,他们并没有单独占用内存,所以被取名为“Sprite精灵”。
什么是Css Sprite?
CSS Sprites 在显著降低 HTTP 请求方面功不可没,但 CSS sprite 可不是个简单的技术。
而学CSS布局的同学应该多少知道CSS Sprites(图片合并)技术,CSS Sprites是一种网页图片应用处理方式,简单的说就是利用CSS的background-position属性,控制显示一张大图片的显示区域。它允许你将一个页面涉及到的所有零星图片都包含到一张大图中去,这样一来,当访问该页面时,载入的图片就不会像以前那样一幅一幅地慢慢显示出来了。
对于当前网络流行的速度而言,不高于200KB的单张图片的所需载入时间基本是差不多的,所以无需 顾忌这个问题。按照yahoo的rules for high performance web sites的原则,应当较少Client与Server端间 的HTTP Request次数。通过CSS Sprites方法将多张图片组装成单独的一张图片,可以有效减少HTTP请求 的次数。
当整幅图片载入完成后,你就可以使用CSS方法通过设置背景位置的方式完成所需图片的准确调用。
加速的关键,不是降低重量,而是减少个数。传统切图讲究精细,图片规格越小越好,重量越小越好,其实规格大小无所谓,计算机统一都按byte计算。客户端每显示一张图片都会向服务器发送请求,所以,图片越多请求次数越多,造成延迟的可能性也就越大。
二、CSS Sprite的使用例子
[原文:http://blog.rexsong.com/?p=746]
1. 图片限制(Image Slicing)
典型如文本编辑器,小图标特别多,打开时一张张跑出来,给用户的感觉很不好。如果能用一张图解决,则不会有这个问题,比如百度空间、163博客、Gmail都是这么做的。
Image Slicing’s Kiss of Death
http://www.alistapart.com/articles/sprites
2. 单图转滚(Single-image Rollovers)
触发切换图片的需求,传统方案得重新请求新图片,因为网络问题经常造成停留或等待。如果能把多种状态合并成一张图,就能完美解决,然后再使用背景图技术模拟动态效果。
ColorScheme Ratings
http://demo.rexsong.com/200608/colorscheme_ratings/
3. 延长背景(Extend Background Image)
如果图片的某边可以背景平铺无限延长,则不需要每个角、每条边单独搞出来,图片能少一个就少一个。其实,这个理论还可以扩展到四角容器里,好处是能大大简化HTML Structure。
CSS Sprites 实现图片标记
示例html:
<html> <head> <meta content="text/html; charset=utf-8" http-equiv=content-type> <base href="http://www.laruence.com" /> <title>CSS Sprites 实现图片标记</title> <body> </head> <style> img.image{ display: none; } dl#officeMap{ margin: 0; padding: 0; background: transparent url(/wp-content/uploads/office.jpg) top left no-repeat; height: 262px; width: 350px; position: relative;} dt{ margin: 0; padding: 0; position: absolute; font-size: 85%; display: none; } dd{ margin: 0; padding: 0; position: absolute; font-size: 85%; } dd#monitorDef{ top: 65px; left: 114px; } dd#monitorDef a{ position: absolute; width: 73px; height: 69px; text-decoration: none; } dd#monitorDef a span{ display: none; } dd#monitorDef a:hover{ position: absolute; background: transparent url(/wp-content/uploads/office.jpg) -109px -317px no-repeat; top: -10px; left: -5px; } dd#monitorDef a:hover span{ display: block; text-indent: 0; vertical-align: top; color: #000; background-color: #F4F4F4; font-weight: bold; position: absolute; border: 1px solid #BCBCBC; bottom: 100%; margin: 0; padding: 5px; width: 100%;} dd#phoneDef{ top: 111px; left: 211px; } dd#phoneDef a{ position: absolute; width: 56px; height: 46px; text-decoration: none; } dd#phoneDef a span{ display: none; } dd#phoneDef a:hover{ background: transparent url(/wp-content/uploads/office.jpg) -211px -373px no-repeat; } dd#phoneDef a:hover span{ display: block; text-indent: 0; vertical-align: top; color: #000; background-color: #F4F4F4; font-weight: bold; position: absolute; border: 1px solid #BCBCBC; bottom: 100%; margin: 0; padding: 5px; width: 100%; } dd#caseDef{ top: 165px; left: 168px; } dd#caseDef a{ position: absolute; width: 81px; height: 87px; text-decoration: none; } dd#caseDef a span{ display: none; } dd#caseDef a:hover{ background: transparent url(/wp-content/uploads/office.jpg) -168px -427px no-repeat; } dd#caseDef a:hover span{ display: block; text-indent: 0; vertical-align: top; color: #000; background-color: #F4F4F4; font-weight: bold; position: absolute; border: 1px solid #BCBCBC; top: 100%; margin: 0; padding: 5px; width: 100%;} dd#notebookDef{ top: 101px; left: 72px; } dd#notebookDef a{ position: absolute; width: 96px; height: 54px; text-decoration: none; } dd#notebookDef a span{ display: none; } dd#notebookDef a:hover{ background: transparent url(/wp-content/uploads/office.jpg) -72px -625px no-repeat; } dd#notebookDef a:hover span{ display: block; text-indent: 0; vertical-align: top; color: #000; background-color: #F4F4F4; font-weight: bold; position: absolute; border: 1px solid #BCBCBC; top: 100%; margin: 0; padding: 5px; width: 150%;} dd#floppyDef{top:126px; left: 45px; } dd#floppyDef a{ position: absolute; width: 64px; height: 39px; text-decoration: none; } dd#floppyDef a span{ display: none; } dd#floppyDef a:hover{ background: transparent url(/wp-content/uploads/office.jpg) -45px -388px no-repeat; } dd#floppyDef a:hover span{ display: block; text-indent: 0; vertical-align: top; color: #000; background-color: #F4F4F4; font-weight: bold; position: absolute; border: 1px solid #BCBCBC; top: 100%; left: 1px; margin: 0; padding: 5px; width: 150%;} </style> <dl id="officeMap"> <dt id="monitor">1. 显示器</dt> <dd id="monitorDef"><a href="javascript:void('laruence');"><span>17'的显示器哦~</span></a></dd> <dt id="phone">2. 电话</dt> <dd id="phoneDef"><a href="javascript:void('laruence');"><span>听筒坏了</span></a></dd> <dt id="case">3. 机箱</dt> <dd id="caseDef"><a href="javascript:void('laruence');"><span>白色的机箱</span></a></dd> <dt id="notebook">4. IBM ThinkPad</dt> <dd id="notebookDef"><a href="javascript:alert('Product by Lenovo! -_!!');"><span>ThinkPad</span></a></dd> <dt id="floppy">5. 外置光驱</dt> <dd id="floppyDef"><a href="javascript:void('laruence');"><span>我不知道这玩意是哪里买的</span></a></dd> </dl> </p> </body> </html>
CSS Sprites + 圆角实例详解
蓝色理想的一篇文章:http://www.blueidea.com/tech/web/2009/6689.asp
三、Google首页的CSS sprite应用:
在Google搜索的首页,body的onload里有这一句:
onload="document.f.q.focus();if(document.images)new Image().src='/images/nav_logo4.png'"
那么来看看这个http://www.google.com/images/nav_logo4.png是什么样子:
这就是Google搜索的CSS Sprite应用。图片文件中基本上包含了Google首页和搜索结果页面用到的所有图形。这些图形被放在了同一个文件中(使得即使看起来是多个图片,但连接数仍然为了1),而且在搜索首页预先加载,这样在搜索结果页面中就会更快速地将它们显示出来。
四、CSS Sprites技术解析
source:http://www.52css.com/article.asp?id=735
原先只在CSS玩家之间作为一种制作方法流传,后来出来个 14 Rules for Faster-Loading Web Sites , 技术人员之间竞相传阅,其中第一条规则Make Fewer HTTP Requests就提到CSS Sprites。于是这个小妖精就火了起来,甚至出现了在线生成工具,势不可挡也。近来国内很多blog都提到CSS Sprites,最著名的例子莫过于 http://www.google.co.kr/ 下方的那几个动画。最新发布的YUI中,也是使用到CSS Sprites,几乎都有的CSS装饰图都被一个 40×2000的图 包办。社交大站Facebook最近也使用了一个 22×1150的图片 承担了所有icon.一时间,CSS Sprites无处不在。
原理
我们知道,自CSS革命以降,HTML倾向于语义化,在一般情况下不再在标记里写装饰性的内容而是把呈现的任务交给了CSS。GUI是缤纷多彩的,少不了各种漂亮的图来装点。新时代的生产方式是,在HTML布满各种各样的钩子(hook),然后交由CSS来处理。在需要用到图片的时候,现阶段是通过CSS属性background-image组合background-repeat, background-position等来实现(题外话:为何我提现阶段,因为未来浏览器若支持content则又新增另外的实现方法)。我们的主角是,你一定猜到了,就是background-position。通过调整background-position的数值,背景图片就能以不同的面貌出现在你眼前。其实图片整体面貌没有变,由于图片位置的改变,你看到只该看到的而已。就好比手表上的日期,你今天看到是21,明天看到是22,是因为它的position往上跳了一格。所以你也大概了解到,CSS Sprites一般只能使用到固定大小的盒子(box)里,这样才能够遮挡住不应该看到的部分。
我们使用YUI的sprite.png举个例子,假如我们有这么一段代码,max代表最大化,min代表最小化,我们需要给它们配上相应的漂亮图片(这样我们的网站才能够吸引人,才可以卖钱,才可以到佛罗里达晒太阳:D):
这两个class都使用同一个图片:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="UTF-8"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Language" content="UTF-8" /> <meta http-equiv="x-ua-compatible" content="ie=7" /> <title>CSS Sprites</title> <style> .min, max { width:16px; height:16px; background-image:url(http://developer.yahoo.com/yui/build/assets/skins/sam/sprite.png); background-repeat: no-repeat; //我们并不想让它平铺 text-indent:-999em; //隐藏文本的一种方法 } <div class="max">最大化</div> <div class="min">最小化</div> </style> </head> <body> <div class="max">最大化</div> <div class="min">最小化</div> </body> </html>
我们看到一团灰,没错,因为我们还没有指定background-position,默认为 0 0,可以看下 sprite.png , 处于这个位置正是灰块。好了,我们要找到代表最大化的加号和代表最小化的减号的位置找出来。经过测量,最大化按钮位于Y轴的350px处,最小化按钮位于Y轴400px处。想一想我们如何才能让它们能够显示出来呢,明显,要向上提升sprite.png,得到代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="UTF-8"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Language" content="UTF-8" /> <meta http-equiv="x-ua-compatible" content="ie=7" /> <title>CSS Sprites</title> <style> .min, max { width:16px; height:16px; background-image:url(http://developer.yahoo.com/yui/build/assets/skins/sam/sprite.png); background-repeat: no-repeat; //我们并不想让它平铺 text-indent:-999em; //隐藏文本的一种方法 } .max { background-position: 0 -350px; } .min { background-position: 0 -400px; } </style> </head> <body> <div class="max">最大化</div> <div class="min">最小化</div> </body> </html>
(注意:为了举例的方便,本例子直接在HTML内置样式,切勿在实践中的非特殊情况使用这种方式)。
优点
我们从前面了解到,CSS Sprites为什么突然跑火,跟能够提升网站性能有关。显而易见,这是它的巨大优点之一。普通制作方式下的大量图片,现在合并成一个图片,大大减少了HTTP的连接数。HTTP连接数对网站的加载性能有重要影响。
缺点
至于可维护性,这是一般双刃剑。可能有人喜欢,有人不喜欢,因为每次的图片改动都得往这个图片删除或添加内容,显得稍微繁琐。而且算图片的位置(尤其是这种上千px的图)也是一件颇为不爽的事情。当然,在性能的口号下,这些都是可以克服的。
由于图片的位置需要固定为某个绝对数值,这就失去了诸如center之类的灵活性。
前面我们也提到了,必须限制盒子的大小才能使用CSS Sprites,否则可能会出现出现干扰图片的情况。这就是说,在一些需要非单向的平铺背景和需要网页缩放的情况下,CSS Sprites并不合适。YUI的解决方式是,加大图片之间的距离,这样可以保持有限度的缩放。
总结
性能压倒一切。CSS Sprites是值得推广的一种技术。尤其适宜用于FIR,比如固定大小的icon替换。为保持兼容性,图片中的各个部分保持一定的距离是一种不错的做法。
六、CSS Sprite优化建议
图片优化
一、对于非动画的GIF更建议使用PNG8因为它同样能做到一样的效果,而且能为你节省10%-30%的文件体积。
二、Photoshop相比起Fireworks,导出同等质量的PNG图片,体积会稍大。而Fireworks虽然做了相应压缩优化,但没有达到最优秀的压缩。
三、我所知的设计软件,对于PNG图片的处理都没做到最优秀的压缩,图片体积还有一定的压缩空间。可以尝试使用下面介绍的”图像优化工具” 做无失真的压缩优化。
四、图片体积及尺寸方面,建议体积保持在100K以内(较为符合国情最佳请求SIZE),size为800px(最佳尺寸)。(从某权威人事中得知,具体无从考证)
CSS Sprites图片切割术
一、CSS Sprites图片顺序合图片由上至下、左至右添加。而background-position一般采用数字组合形式定位,这样能减少维护带来的不必要麻烦。
二、不建议CSS Sprites图片中保持一定的间距,因为文件size增大而增加文件体积。
三、CSS Sprites图片中把颜色较近或相同的组合在一起可以降低颜色数,因为少色数的图片文件体积会相对的小。
四、size相同的CSS Sprites图片中留有较大空隙,某程度上多数情况会增大了体积,所以CSS Sprites的图片不要有空隙。
五、在size相同的CSS Sprites图片中,垂直排列的图片会比水平排列的文件体积要大。
六、在CSS Sprites图片中,水平排列的图片会比垂直排列的文件体积要大。
七、图片对等合并:应用CSS Sprites图片时,适当地把对等相同的图像合并,以节省空间及减少体积。
八、区分开不需要合并的图像:如当前用户确定只显示一种状态或一个级别时,不必要把其他的级别或状态的图片合并。
九、黄金切割位:在CSS Sprites图片的最右或左边为最灵活动位置最适宜摆放文本前的icon,因此不会受到其它CSS Sprites图片干预,也不需要预留一定的行宽。
五、些中文的CSS Sprites样式生成工具
CSS Sprites 样式生成工具
http://www.cssforest.org/blog/index.php?id=129
CSS Sprites图片样式在线生成
官方网址:http://spritegen.website-performance.org/
还有中文版:http://cn.spritegen.website-performance.org/
ImagesSprite
下载:http://demo.tglgx.cn/ImagesSprite/ImagesSprite1.1.1.rar
发布介绍:http://blog.tglgx.cn/post/2009/08/04/ImagesSprite-V111-Betae58f91e5b883.aspx
其他相关的图像优化工具
网上流传的优化工具常见的如:ImageMagick、PNGGauntlet、pngcrush、pngrewrite、Optipng、PNGOut等