无处不在的CSS sprites——是为数不多的几个可以绕过“逐渐流行”阶段,而直接让自己成为CSS最佳实践的Web设计技巧中的一个。尽管在A List Apart对它进行一个解释以及赞同认可这种方式之前,它还没有真正地流行。它最早是由Petr Stanícek.在2003年7月提出来作为一个CSS的解决方案。
Ah, the ubiquitous CSS sprites — one of the few web design techniques that was able to bypass “trend” status almost instantly, planting itself firmly into the category of best practice CSS. Although it didn’t really take off until well after A List Apart explained and endorsed it, it was discussed as a CSS solution as early as July, 2003 by Petr Stanícek.
当今许多web程序员对这项技巧(CSS sprites)有着很娴熟的应用能力,介绍CSS sprites的教程和文章也是不计其数。几乎在每一篇教程中,都要求设计师以及程序员应该实施CSS sprites以减少HTTP请求和节省带宽。迄今为止,这项技术已经被许多网站所应用了,包括亚马逊,正在使用着极大数量的sprites图片。
Most web developers today have a fairly strong grasp of this technique, and there have been countless tutorials and articles written on it. In almost every one of those tutorials, the claim is made that designers and developers should be implementing CSS sprites in order to minimize HTTP requests and save valuable kilobytes. This technique has been taken so far that many sites, including Amazon, now use mega sprites.
可是 这项技术被广泛热议的带来的好处真的值得么?设计师们是否可以在没经过仔细考虑所有方面的因素的情况下转而使用CSS sprites?在这篇文章中,我将来讨论一下CSS sprites的一些赞同或者反对使用CSS sprites的意见,尤其集中在大量使用的sprites,以及为什么这样子使用CSS sprites在许多情况下是等同于浪费时间。
Is this much-discussed benefit really worthwhile? Are designers jumping on the CSS sprite bandwagon without a careful consideration of all the factors? In this article, I’m going to discuss some of the pros and cons of using CSS sprites, focusing particularly on the use of “mega” sprites, and why such use of sprites could in many cases be a waste of time.
拥护者们提出的一个CSS sprites的好处是页面中图片的装载时间(或者说在有许多sprites图片的情况下的单张图片的装载时间)。一张包含了所有必须的图像的GIF图片是否会拥有比相同内容的切片图像更小的文件体积?这仍然是被人争论不休的。单张GIF图片只和一个颜色表关联着,而在切片GIF模式下,每个图像都会拥有一个自己的颜色表,这样会增大文件体积。同样的,单张JPG或者PNG的sprites图像会比切片为多张图像更节省文件体积。但是这样做带来的效益会很显著么?
One of the benefits given by proponents of the sprite method is the load time of the images (or in the case of mega sprites, the single image). It’s argued that a single GIF image comprising all the necessary image states will be significantly lower in file size than the equivalent images all sliced up. This is true. A single GIF image has only one color table associated with it, whereas each image in the sliced GIF method will have its own color table, adding up the kilobytes. Likewise, a single JPEG or PNG sprite will likely save on file size over the same image sliced-up into multiple images. But is this really such a significant benefit?
默认情况下,浏览器会缓存所有的图片——不管这张图片是sprites的还是普通的。所以,尽管在使用sprites技术的时候,带宽确实会节省。但是这也只在页面第一次加载的时候回发生,当其他页面使用了相同的图片地址,浏览器会使用缓存而不是重新下载。
By default, image-based browsers will cache all images — whether the images are sprites or not. So, while it is certainly true that bandwidth will be saved with the sprite technique, this only occurs on the initial page load, and the caching will extend to secondary pages that use the same image URLs.
Firefox使用缓存来显示亚马逊网站的图像(你可以在地址栏输入“about:cache”来查看)。
The Firefox cache displaying images from amazon.com that the browser cached (type “about:cache” in the address bar in Firefox to view this feature).
当你将上述的情况与现在互联网的速度已经比css sprites这项技术出现的时候(大约是2003年-2004年)要快得多结合起来的时候,那么就没有什么理由来使用sprites技术了。我并不是指css sprites不能被使用,而是说它们不应该被过度地使用而仅仅是为了获得有限的好处。
When you combine that with the fact that internet speeds are higher on average today than they were when this technique was first expounded upon in 2003-2004, then there may be little reason to use the mega sprite method. And just to be clear, as already mentioned, I’m not saying sprites should never be used; I’m saying they should not be overused to attain limited benefits.
想象一下一个拥有三个状态图片的按钮的sprites是如何创建的:不同的状态图片需要紧靠着其他状态图片放置着,以形成单张的图片。在你的Photoshop的原型(或者其他软件)中,你没有使不同的状态的图片以这种方式相互毗邻;它们需要被重新裁剪以及组合成一张新的独立图片,这需要在你的网站原型之外独立制作。
Think about how a simple 3-state image button sprite is created: The different states need to be placed next to one another, forming a single image. In your Photoshop mockup (or other software), you don’t have the different states adjacent to each other in that manner; they need to be sliced and combined into a new separate image, outside of the basic website mockup.
如果这时候有任何关于图片状态的修改,整个图片就都需要重新地编辑和保存。某些开发者可能没有这个烦恼。可能他们在页面原型之外还另外保存了它们的按钮状态,从而可以方便地修改。但是这样复杂的事情,远没有使用单张图片来得简单。
If any changes are required for any one of the image states, the entire image needs to be recompiled and resaved. Some developers may not have a problem with this. Maybe they keep their button states separate from the mockup in a raw original, making it easier to access them. But this complicates things, and will never be as simple as slicing a single image and exporting it
为了节省几千字节的带宽以及节省好几次服务器请求(只在页面第一次被加载的时候才会发生,其他时候都是读取浏览器缓存)这么细小的利益,sprites技术是不是真的是一项实用的解决方案呢?
For the minimal benefit of a few kilobytes and server requests saved (which only occurs on initial page load), is the mega sprite method really a practical solution for anything other than a 3-state button?
当一张sprites图片导出后,麻烦并没有消停。尽管只要你习惯了的话,将按钮sprites加入你的CSS代码中会很容易,但是其他sprites就不会这么简单了。
After an image is sliced and exported, the trouble doesn’t end there. While button sprites are simple to code into your CSS once you’re accustomed to the process, other kinds of sprites are not so simple.
一个按钮通常会是一个拥有着固定宽度的<ul>元素。如果按钮的sprites图片与其他按钮是独立的,那么这很简单:<ul>的宽度和高度会与列表元素以及锚点的宽高相同,sprites的每个状态都是对齐的。基于每个按钮的宽高,sprites的位置坐标会很容易计算。
A single button will usually be a <ul> element that has a set width. If the sprites for the button are separate for each button, it’s simple: The width and height of the <ul> will be the same as the width and height of the list item and anchor, with the sprite aligned accordingly for each state. The position of the sprite is easily calculated based on the height and/or width of each button.
但是如果放在一个大型的sprites上,比如上面说到的亚马逊使用的,或者Google使用的这张的时候会怎样?你能想象一下维护这样一个文件,然后在CSS中修改元素的位置?还有第一次创建这些CSS代码需要花费的精力?相对于一个简单的很容易计算位置的按钮sprites,大型是sprites通常需要持续的维护代码以及重新对齐图片。
But what about a mega sprite, like the one used by Amazon, mentioned earlier, or the one used by Google? Can you imagine maintaining such a file, and making changes to the position of the items in the CSS? And what about the initial creation of the CSS code? Far from being a simple button whose state positions are easily calculated, the mega sprite will often require continuous testing and realigning of the image states.
部分用来排列Google的sprites图片的代码
Some of the CSS used to position Google’s sprite image
事实上,亚马逊使用的sprite节省了30或者更多的HTTP请求,这绝对是一个很显著的性能上的改善。但是当这个好处与开发和维护的成本,还有浏览器缓存以及互联网的速度相比起来,大面积地使用sprites就不是那么令人信服了。
It’s true that the Amazon sprite saves about 30 or more HTTP requests, and that is definitely a significant improvement in performance. But when that benefit is weighed against the development and maintenance costs, and the caching and internet speed issues are factored in, the decision to go with sprites in the mega format may not be so convincing.
当然,有些人认为sprites不会引起他们的头疼。在许多情况下,当一个sprites创建以及编码之后,它就很少再被修改了,而且不会受到网站维护的影响。如果你认为sprite的维护不会成为你的问题,那么最好的选择就是使用大型的sprites方法。
Of course, some may feel that sprites do not cause a major headache for them. In many cases, after a sprite is created and coded, it’s rarely touched again, and isn’t affected by any ongoing website maintenance. If you feel that sprite maintenance won’t be an issue for you, then the best choice may be to use the mega sprite method.
另外一个不推荐过度使用CSS sprites的原因是它会导致开发者不正确地使用背景图像,有经验的开发者在他们的项目中会考虑到界面的可用性而找到并不是所有的图片都应该成为背景。传达重要内容的的图片应该以内嵌代码的形式实现出来,而背景图像应该在按钮或者装饰性的元素上使用。
Another reason not to promote the overuse of CSS sprites is that it could cause developers to use background images incorrectly. Experienced developers who consider accessibility in their projects understand that not every image should be a background. Images that convey important content should be implemented through inline images in the XHTML, whereas background images should be reserved for buttons and decorative elements.
亚马逊网站将内容图片以内嵌形式实现,装饰的图片以背景实现。
Amazon correctly places content images as inline elements, and decorative ones as backgrounds.
因为CSS sprites受到了高度的重视,一些初级的开发者出于节省HTTP请求的原因,可能会不正确地推断出所有切片的图像都应该以背景图片的形式展示——即使那张图片传达了很重要的信息。这会导致站点缺乏易用性,以及限制了HTML语言中tittle和alt属性的潜在好处(译者注:丢失alt和tittle标签的一个后果,可能会导致盲人使用的专用发音上网机器无法识别出图像要传达的内容从而发音,因为这些标签都没有了)。
Because of the strong emphasis placed on using CSS sprites, some beginning developers intending on saving HTTP requests may incorrectly assume that all sliced images should be placed as backgrounds — even images that convey important information.The results would be a less accessible site, and would limit the potential benefits of the title and alt attributes in the HTML.
所以,CSS sprites其本身并没有错,而且也不会引起易用性的问题(实际上,当被正确使用的时候,他们有助于改善可用性),过度推荐使用sprites而没有辨别出好处与坏处,可能会妨碍网站在易用性以及生产力方面已经取得的成果。
So, while CSS sprites in and of themselves are not wrong, and do not cause accessibility problems (in fact, when used correctly, they improve accessibility), the over-promotion of sprites without clearly identifying drawbacks and correct use could hinder the progress the web has made in areas of accessibility and productivity.
许多人会争论,尽管减少HTTP请求是改善一个站点的性能的最重要的部分。下面这事情也应该被记住,就是一项研究表明40%-60%的站点的日常访客都是以空白的浏览器缓存来访。这应该足够支持大型sprites应该在各种情况下使用的观点吧?也许吧。特别是当你认为第一次访问站点的访客有多重要的时候。
Many will argue, however (and for good reason) that the most important part of improving a site’s performance is minimizing HTTP requests. It should also be noted that one study conducted showed that40-60% of daily website visitors come with an empty browser cache. Is this enough to suggest that mega sprites should be used in all circumstances? Possibly. Especially when you consider how important a user’s first visit to a website is.
Firefox的插件YSlow可以分析显示出当前的HTTP请求数
The YSlow Firefox add-on that analyzes performance shows the number of HTTP requests being made
年代比较久远的浏览器一般只支持两个并发的HTTP连接,Firefox从3.0版本,IE从8开始默认支持6个并发的HTTP连接。这意味着对每个服务器发出6个并发连接。Steve Souders这么说:
While it is true that older browsers generally only allowed two simultaneous HTTP connections, Firefox since version 3.0 and Internet Explorer 8 by default allow 6 simultaneous HTTP connections. This means 6 simultaneous connections per server. To quote Steve Souders:
明白这是每一个服务器的基础是很重要的。使用多个域名,比如1.mydomain.com,2.mydomain.com,3.mydomain.com等等,允许Web开发者可以以倍数增加每个服务器的连接数限制。这种做法在所有域名都是指向同一个IP地址的CNAME记录的时候仍然起效。
It’s important to understand that this is on a per server basis. Using multiple domain names, such as 1.mydomain.com, 2.mydomain.com, 3.mydomain.com, etc., allows a web developer to achieve a multiple of the per server connection limit. This works even if all the domain names are CNAMEs to the same IP address.
所以,尽管现在在按钮状态之外使用CSS sprites可能还有好处,在未来,当互联网连接速度增长了,以及新版本的浏览器表现出更好的性能,使用大型sprites的好处就变得无关紧要了。
So, while there could be a benefit to using CSS sprites beyond just button states, in the future, as internet connection speeds increase and newer browser versions make performance improvements, the benefits that come from using mega sprites could become almost irrelevant.
大型sprites的支持者们还有另外一个观点就是sprites可以使用sprites生成器来创建。对于这些工具,在本文之外,已经有很多详细的讨论以及评测,所以我也不再赘述。但是从我对这些工具的研究上来说,它们所能提供的帮助仍然是有限的,sprites的维护仍然需要数目可观的工作时间,这与取得的好处仍然是相互冲突的。
Another argument in favour of mega sprites is the apparent ease with which sprites can be created using a number of sprite generators. A detailed discussion and review of such tools is well beyond the scope of this article, so I’ll avoid that here. But from my research of these tools, the help they provide is limited, and maintenance of the sprites will still take a considerable amount of work, which again should be weighed against the benefits.
有些工具,比如Fondue项目,提供了CSS输出的选项。Setve Souders的SpriteMe工具是另外一个提供了CSS输出选项的工具。SpriteMe会将一个现有的网站的背景图像转换成一张sprite图片(这就是我曾经说的“大型”sprite),你可以下载图片以及必要的CSS代码并插入到页面中。尽管这些工具可以帮助创建sprites图片,但是它们在sprites的维护上并没有提供太多的帮助。Souders的工具在一个网站重新设计以及重新排列的时候就会显得无用了,而这个时候,能提供帮助的似乎只有还没使用大型sprite方法的设计。
Some tools, like the one by Project Fondue, offer CSS output options. Steve Souders’ tool SpriteMe is another one that offers CSS coding options. SpriteMe will convert an existing website’s background images into a single sprite image (what I’ve been referring to as a “mega” sprite) that you can download and insert into your page with the necessary CSS code. While this tool will assist with the creation of sprites, it doesn’t seem to offer much help in the area of sprite maintenance. Souders’ tool seems to be useless for a website that is redesigned or realigned, and only seems to provide benefit to an existing design that has not yet used the mega sprite method.
这些工具在不断地改进中,未来可能会出现新的工具(来帮助创建CSS sprite)。但是有没有这种可能,在了解了上述的这些坏处之后,开发人员仍然将精力集中在这个需要很多努力,但是收益很小的事情上面呢?
Improvements to current tools could be made, and newer tools could appear in the future. But is it possible, due to some of the drawbacks mentioned above, that developers are focusing a lot of effort on a very minimal gain?
如前所述,HTTP请求的数量是站点性能的一个重要因素。但是还有其他方法可以减少这个数字,包括合并脚本以及样式表,或者是使用远程地址的库文件(译者注:比如将你的jQuery库地址换成Google服务器上的jQuery库地址)。
As mentioned, the number of HTTP requests is an important factor to consider in website performance. But there are other ways to lower that number, including combining scripts and stylesheets, and using remote locations for library files.
在HTTP请求之外,开发者还有其他方面可以改善站点的性能。这些技巧包括:GZip压缩,正确的外部脚本文件的引用,优化CSS,缩小过大的JS文件,改善Ajax性能,避免使用已知的会引起性能问题的JS,还有其他的。
There are also areas outside of HTTP requests that a developer can focus on to improve site performance. These might include GZipping, proper placement of external scripts, optimizing CSS syntax, minifying large JavaScript files, improving Ajax performance, avoiding JavaScript syntax that’s known to cause performance issues, and much more.
YSlow指示了除了HTTP请求之外的许多可以改善网站性能的因素
YSlow indicates many areas outside of HTTP requests that can improve site performance
如果开发者花时间来考虑影响网站性能的所有因素,正确地衡量好处与坏处,那么应该就有个很好的理由来避免过度使用CSS sprites,以及投入更多关注在可以获得超值的性能回报的因素上面。
If developers take the time to consider all factors in website performance, and weigh the pros and cons correctly, there may be good reason to avoid overusing CSS sprites, and focusing on areas whose performance return is worth the investment.
请不要误解我在此所说的任何事情。许多顶尖的博主和开发者多年来都在赞扬使用sprites的好处,近几年来开始把这个建议推广开来,变成推荐使用大型的sprites——这些观点应该认真的考虑。尽管不是所有人都有在一个有着完整的制度和系统,可以让网站的维护工作变得简单和流水线化的公司工作的机会。我们当中的许多人都是独行侠,或者是从别人手中接过项目。在这种情况下,投入使用大型的sprites会让你入不敷出。
Please don’t misinterpret anything that I’ve said here. Many top bloggers and developers have for years extolled the benefits of using sprites, and in recent years taken those suggestions further in promoting the use of mega sprites — so those opinions should be taken seriously. However, not everyone has the luxury of working in a company that has policies and systems in place that make website maintenance tasks simple and streamlined. Many of us work on our own, or have to inherit projects created by others. In those cases, mega sprites may cause more trouble than they’re worth.
http://www.iamsolari.com/2010/04/05/css-sprites-useful-technique-or-potential-nuisance-translated/