This article has been revised and re-written several times since its very first publication in 2007, to keep the information current. The most recent revision was done by Flip Stewart in January 2015.
What are CSS Sprites?
Spoiler alert: they aren’t fairies that write your stylesheets for you. I wish. In short: CSS Sprites are a means of combining multiple images into a single image file for use on a website, to help with performance.
Sprite may seem like a bit of a misnomer considering that you’re creating a large image as opposed to working with many small ones, but the history of sprites, dating back to 1975, should help clear things up.
To summarize: the term “sprites” comes from a technique in computer graphics, most often used in video games. The idea was that the computer could fetch a graphic into memory, and then only display parts of that image at a time, which was faster than having to continually fetch new images. The sprite was the big combined graphic.
CSS Sprites is pretty much the exact same theory: get the image once, and shift it around and only display parts of it. This reduces the overhead of having to fetch multiple images.
Why use CSS Sprites?
It may seem counterintuitive to cram smaller images into a larger image. Wouldn’t larger images take longer to load?
Let’s look at some numbers on an actual example:
Image | File Size | Dimensions |
---|---|---|
canada.png | 1.95KB | 256 x 128 |
usa.png | 3.74KB | 256 x 135 |
mexico.png | 8.69KB | 256 x 147 |
That adds up to a total of 14.38KB to load the three images. Putting the three images into a single file weighs in at 16.1KB. The sprite ends up being 1.72KB larger than the three separate images. This isn’t a big difference, but there needs to be a good reason to accept this larger file… and there is!
While the total image size (sometimes) goes up with sprites, several images are loaded with a single HTTP request. Browsers limit the number of concurrent requests a site can make and HTTP requests require a bit of handshaking.
Thus, sprites are important for the same reasons that minifying and concatinating CSS and JavaScript are important.
How do you use CSS Sprites?
Here’s an example sprite, with three different countries flags combined into a single image:
You set the same background-image
on several CSS classes and set the background position and dimensions of the individual classes to display a single portion of the sprite. Here’s some code that demonstrates the concept:
.flags-canada, .flags-mexico, .flags-usa {
background-image: url('../images/flags.png');
background-repeat: no-repeat;
}
.flags-canada {
height: 128px;
background-position: -5px -5px;
}
.flags-usa {
height: 135px;
background-position: -5px -143px;
}
.flags-mexico {
height: 147px;
background-position: -5px -288px;
}
If you’re thinking that there has to be a way to automate this so that you aren’t manually creating these sprites and then adjusting your stylesheet to match, you’re right, and you’re in luck!
Generate Sprites with Grunt / Gulp / Node
If you’re using Grunt, Gulp, or Node in general, css-sprite (now called sprity) is a wonderful node package that creates sprites from a glob of images. Sprity has a lot of great features including formatting output as PNG, JPG (or Data URIs of those), and stylesheet generation in CSS, LESS, Sass, and Stylus.
To compile sprites via command line, install css-sprite globally with:
$ npm install sprity -g
Then, to generate sprites and the corresponding stylesheet, run:
$ sprity ./output-directory/ ./input-directory/*.png
For more information on using css-sprite with Grunt or Gulp (or many other environments), head over to the project’s repository on GitHub.
Generate Sprites with Compass
Generating sprites with Compass takes some additional setup and maintenance, but if you’re already using Compass, it fits in well with your existing workflow.
Start by creating a directory within your `images` directory (yes, it does need to be inside your `images` directory to work) with a name that corresponds to the sprites you’d like to create. Ensure that the images you’re converting to sprites are PNGs and place them in your new directory. I’m creating flag sprites, so I’ve named my directory flags and placed three PNGs in the directory.
In a new SCSS file that I’ve called `flags.scss` (the name here is not important), the following three lines will, in order, import Compass’ sprite making tools, glob import the PNGs to be converted to sprites (notice that the path here does not include images/), and then generate the CSS for the sprites. Be mindful that the @include statement’s middle word needs to match the directory in the line before it.
@import "compass/utilities/sprites";
@import "flags/*.png";
@include all-flags-sprites;
This is a fairly simple process for generating sprites, but it has a few drawbacks/oddities:
- The generated CSS does not include widths or heights for the sprites.
- There is no shared class between the sprites; the background-image is applied to each class.
Generating Sprites with ImageMagick
ImageMagick can be used to create a spritesheet from the command line with the following commands:
convert *.png -append sprites.png # append vertically
convert *.png +append sprites.png # append horizontally
This will take all the PNG files selected by the glob and concatenate them into a single file, but will not create the corresponding stylesheet. If you use ImageMagick to create your sprites, you may want to read the section below on using Sprite Cow.
Using Sprite Cow with your Sprites
Sprite Cow is a hosted tool for generating a stylesheet corresponding to your sprites. It doesn’t make the sprite for you, it just helps you get numbers you need to use the sprite (the width, height, and background-position of individual parts of the sprite). It boasts 2x image compatibility and a simple interface for quickly designating which areas of the sprite make up each image to create CSS for. You just click the part you need and it gives you the CSS you need.
Generate Sprites with Spritepad
Spritepad is another hosted solution for creating sprites. With Spritepad, you upload individual images, position them however you’d like, and the CSS is updated in real time. When you’re done, download the image and copy the CSS over to your project.
Generate Sprites with SpriteMe
SpriteMe is a bookmarklet that generates a sprite based on what it finds on the current page. So essentially you’d develop without using sprites at all, then use this to sprite things together at the end. Here’s a workflow explaining how that would work.
Should my sprites be horizontal or vertical?
One option is neither. Compact them into a grid, making the smallest size, dimensionally that you can. The dimensional size of an image plays a role in how much memory the image will take up when being used, so the less the better. If you end up laying out your own sprite, Sprite Cow is a good tool to help with the CSS generation part.
If, for simplicity, you’re going to pick one or the other, one way to do that is to look at the largest width and the largest height of your image files. If the largest width is greater than the largest height, the sprite sheet should be arranged horizontally. If the largest height is greater than the largest width, vertically. If you’re using a generation tool, they will generally make this choice for you.
In some situations, it may actually make sense to lay out a sprite diagonally. This can make it possible to use a sprite in an area of unknown width and height, which is pretty cool.
Although another possible way to get around that is using a pseudo element.
Alternatives
There are a few alternatives to CSS sprites, but, as you might expect, they each have their own benefits and drawbacks.
Data URIs
Data URIs allow you to embed the image data directly into a stylesheet. This avoids additional HTTP requests for images, making it essentially the same thing as a sprite, without the fancy positioning.
Icon Fonts
Icont fonts are similar to sprites in that the achieve the same thing: combining multiple images into a single request.
SVGs
SVG images can be combined into a sprite as well and used as an icon system. It’s a slightly different approach though, utilizing the syntax and strengths of SVG. You may need to think about a fallback system though, as SVG doesn’t have as deep of browser support as CSS background-image (which essentially has no browser support issues at all).
Grunticon and Iconizr are possibilities for working with SVG sprites that help with the fallbacks.
Using <img> and object-position
Robin Rendle has a great post on this clever technique here.
Examples
- Mozilla Developer Network uses sprites to switch between different states when toggling their top level navigation.
- Mailchimp uses sprites (background-image SVG) for their sidebar navigation in various states.
- Mapbox uses an icon font for their smaller icons used throughout the site, but uses fairly high resolution sprites for social media and press logos
Good post! Will be one to bookmark and look over!
Another good thing about CSS sprites is that you can do columns easy as well. For a previous website I tried having three columns equal length and it was next to impossible until I used sprites for one background image.
I’ve seen this technique used for a number of years, but mostly in navigation before.
While I understand the principles behind it, it really just doesn’t make a lot of practical sense (aside from the request argument) to do this.
The reason I mainly dislike this probably comes from my bias of having worked on a site using it, that I didn’t originally design. I didn’t have the original graphic files, and it was a pain to have to try to recreate it from scratch (when all I wanted to have to do was change one little icon and not have to worry about the other 4 in the same graphic).
Better site performance, maybe a little. I would say the biggest time hit on most sites are server-side these days, especially with all the database driven platforms out there now.
It’s worth it if you’ve got the time I say, but I say especially if you are under deadlines it could cost you more than it’s worth.
@spiralstarez: I think you make some good points. Updating graphics is a lot bigger of a pain with sprites, especially if you don’t have the native files.
I think there is probably a sweet spot where using CSS sprites is the most beneficial to use. If you have a fairly low traffic site on a decent server…yeah…it probably doesn’t matter to much. If you are running a super high traffic news portal like yahoo.com, there are definite benefits and using them to reduce server requests is a must.
Interesting article.
I would point out, however, that if a user increases font-size, then the neatness of this option starts to fail as you get to see the other images revealed. Perhaps a slight change in approach would work a little better: make the composite image run horizontally, rather than vertically.
Also min-heights might be employed in the css to prevent the images collapsing when font-size is decreased by the user (not that that is so likely).
Chris,
Nice job writing this up in a manner that most people can understand. I have been using sprites for rollover navigation for quite some time and I do find it’s the best way to go in terms of page load times.
Lucy makes a great point about sprites having trouble when font sizes scale, Definitely want to encourage people to test their designs at a variety of font sizes.
Also – if you’re going to talk sprites, you have to mention one of the coolest sprite examples out there on Ask.com. Here’s a link directly to their sprite image: http://sp.ask.com/i/h/sprite/b1.png
Cheers,
Scott
Great article
As you mentioned at the start I had used them for individual on-off navigation states but had never thought of this technique for multiple images!
Thanks Chris!
I had seen this done before – but your way of explaining it makes a lot more sense.
@lucy: Great point! Yep, you can absolutely make your sprites run horizontally instead of vertically. In fact, you can do both, Just take a look at the awesome example sprite that Scott linked to below (from ask.com), which uses all kinds of X and Y positioning.
@Chris & Matt & Scott: Thanks! I appreciate your guys support.
Lucy Barker,
That explains why I’m not seeing it right. I was reading this in a feed-reader and saw underlines under the squares when I clicked on the example. They were the tops of the next squares. When I opened the example in Firefox, the bottoms of the squares were cut off, and increasing the font size brought them back, but also revealed some of the square below.
Thanks for this article, it really enlightened me on my strategic approach to websites. Thanks again.
Leaving more whitespace between images can be a solution to the degradation which happens when the font-size is increased or decreased.
http://www.shacknews.com has been using CSS Sprites for a few years now.
Ugh. Ultimately, the sane solution is to *stop using bitmapped graphics*. As screens get higher and higher resolution, just using SVG would be so much nicer. Pity you can’t rely on it being available (time was, you couldn’t rely on PNG being available, of course, so maybe one day…).
Maintainability for this approach could be achieved pretty easily by incorporating the process of combining images into the system build. The SCCS would maintain the original separate images, and it’d be at build time that they’d be turned into the single super-image. The stylesheets would have to be done as templates, using artifacts of the imagine combining step to fill in the actual super-image coordinates.
I first came across sprites on paulstamatiou.com
Btw, is there any way to use sprites for elements other than links, and for repeating bg? I’m doubtfull abt the last one.
Excellent post. Fascinating reading. I’ve posted it over at InformedNetworker.Com…and I’d be happy to have you submit your article links for any future postings such as these you feel might be useful for your readership.
@Sumesh: I don’t think there would be any practical way to use sprites for a repeating image, just because the best way to do it is to know your height and width of the element you will be using the sprite on and it is unlikely you would know that for an element you are trying to use a repeated image on.
But you can absolutely use sprites for things other than links. Anything that accepts the background-image property in CSS is fair game.
Yahoo! uses bg sprites for repeating backgrounds (here’s an example — from their home page ) pretty extensively, but your caution, as well as the cautions above, about knowing your width/height are really important. It’s problematic, especially if you’re just starting off. It’s definitely an advanced technique, and an easy one to be tripped up on. (I’ve done it, and been tripped!)
If you ‘have’ to do it, I think the key is plenty of whitespace between backgrounds and extensive testing.
Keep an eye out for css3. It won’t be in many browsers soon, but we should eventually be able to use sprites for fully repeating backgrounds.
http://www.css3.info/image-sprites-syntax/
Part of the reduction in size is simply because GIF is limited to 256 colors, so this isn’t a totally fair comparison. If you closely examine the colors in the image after splicing, you’ll see that they are subtly different from what you had before. For most icons you can’t tell the difference, but on an effect with heavy gradients, you would notice it. Unfortunately this effect compounds itself as you add more images. If you use PNG – you’ll see that most of the reduction in file size goes away.
Of course, the main point is that cutting down on the number of files you have to grab from the server is a good thing (even with pipelining and HTTP/1.1), and that point stands. But given the reduction in clarity, (and if you use GIFs, image quality) is that worth the cost?
Here’s a CSS sprites tool I did:
http://www.csssprites.com
(The UI is pretty ugly, I must admit, but if anyone wants to contribute a stylesheet, that would be much appreciated, link-back-acknowledged, etc)
One small notice – if your image sprites are .PNG files with alpha channel, the transparency hacks for IE6 will break your css styles. AlphaLoader filter doesn’t support background-position property,the backgrounds are automaticly positioned in the upper left corner. so you’ll have to serve gif sprites to IE6 or use single PNG images for it.
@Some Jackass: You are right, part of the file size savings comes from the fact that the total color palette for all the images will be forced into 256 colors at a maximum rather than having 256 for each image. But even if you used few enough colors on each image there would be no compromise, there would still be slight savings from not having to repeat file format code each time. Not much, but some.
@Matas Petrikas: Thanks for pointing that out. In short, when using PNG hacks, don’t use sprites.
Re: Matas’ comment – it’s OK to use PNG sprites without any hacks in those cases:
a/ your PNG has constant transparency (true/false, like a GIF). In this case the so-called PNG8 format can be used where you have 1 bit for transparency
b/ the PNG has variable transparency, but is saved with 4 bits for transparency
PNGs for a/ can be produced by lots of tools, for example imagemagick on the command line:
> convert my.png PNG8:my8.png
PNGs of type b/ are only produced (AFAIK) by Fireworks (Fireworks calls them PNG8)
@Stoyan: Could you explain a bit more about the 4-bit PNG transparency? I’m really only familiar with PNG-8 and PNG-24 from Photoshop. Using PNG-8 (1 bit transparency), no hack would be needed. Using PNG-24, using the hack would break the sprite because of the hack. Are you saying there is another way to save a PNG that would support alpha transparency with no hack needed?
Hey Chris, a differet format is what I meant – Fireworks calls it PNG8 but looking at the result image with imagemagick’s “identify” I see 4 bits for transparency.
The long story here:
http://www.sitepoint.com/blogs/2007/09/18/png8-the-clear-winner/
I don’t know how extensively this Fireworks PNG8 was tested. I ran through a test run with one image, which seemed to work fine, and then went to use it with a gray gradient image, and it did not render properly. There might be an algorithm that tries to detect what “should” be alpha transparency or something, but it was definitely “broken” for this one case.
I wouldn’t rely on it.
@Greg with PNG 8, “Pixels are either solid or completely transparent, but never partially see-through.” – so it wouldn’t have work with a gradient as the alpha levels would have needed to vary
Love the comment bout Chuck Norris :P I don’t think I’ll really use it, the space saved in minimal with today’s broadband speeds. I may try it out in future designs just for the heck of it though :P
I think you missed the main point – the saving is with the 9 fewer requests – avoiding 4-9 latency hits for the end user (which doesn’t depend on their connection speed) and giving your server less work to do.
Great article, but I have to pick at one technical issue. One of the main reasons for slicing was *not* to trick the eyes into a faster loading experience, but rather to optimize large gifs.
You see, a gif can be significantly compressed if the corresponding color pallete for that particular image can be minimized. Therefore a large area within a gif of the same (or similar) colors can be factored out, via slicing, to greatly reduce the total size of the whole image. In other words, the size of all the slices combned would be less than that of the whole image, unsliced.
Of course, the landscape has greatly changed and with increasing usage of jpegs and PNGs, and increased bandwidth of users, response time (round trip) becomes much more of a factor than simply bandwitdh. Nevertheless… great article!
@Shane: You know, I remember when I was sitting there writing this, I was paused tapping my forehead thinking of just why the heck we used to cut apart images like that. I used to to it all the time, but I couldn’t remember for the life of me why I did it. I don’t think I ever thought about it, it was just the standard.
But yes, you are absolutely right, the real reason was the color indexing power of GIFs.
But what about applying alt tags to the images for 508 compliancy? Is it possible?
You don’t do that for background images.
@Kakupacal – the sprites technique is best suited for background (decoration) images. Your page should work well and be accessible even with no background images.
For “content” images, it’s still best to use img tag with alt attribute. For example a photo in a news article is part of the content and should be an img tag
Yahoo DevNet does believe “CSS Sprites are the preferred method for reducing the number of image requests” but they have a lot of other recommendations for making fewer HTTP requests as well, besides their general list of best practices.
I really appreciate the attention to detail in this post, Chris!
Thanks for putting this together. Finally a nice static image example. I would like to set this up for our website but I think it would be a good idea to get all the images I want first so i don’t have to go through the process again in a couple of weeks.
Thanks so much
Chris
Are there any known problems for this in IE5/6?
I’ve put sprites to use in 2 areas for a new site on a larger scale than i have before.
previously I had done this just for the down and hover state of individual nav elements. then put them in their definded spot.
this time i have 1 graphic for 5 individual links both having down and hover states.
in all browsers the site is working right, so far, except in IE5 and 6.
its duplicating the whole image at its full width on the Y axis 4 times. then at the 5th time its showing the button with its hover state as it should.
lol driving me crazy.
i dont expect anybody to solve this problem as its hard to explain but I’m hoping somebody has had some problems with sprites in IE6 that can offer some information on the background repeating or at least seeing that effect despite having no-repeat value called on the declaration block.
I have yet to figure out exactlly what was causing my problem but I think it did have something to do with applying the same 1 image to all A elements in my UL instead of individual images for each A element.
i had to apply a 0px height for ie to the LI and A elements of my navigation.
odd.
This is great. I have used this technique before with 3 state navigation… 1 image with the position manipulated by the css based on off/hover/active. This really opens things up. Where you would maybe dynamically load images in a rotation on a page load, rather than a dynamic image load, just make it dynamic css positioning. Thanks for pointing out the further possibilities of this technique!
Thank you,
Jim Summer
Jacksonville Web Design
http://tentonweb.com/
Really useful hint, there are lots of possible implementations of this technique.
I’ve found myself preferring the “slicing” of images, I hope it wouldn’t be hard to change it.
Actually Chuck said “All great technique require great dedication”.
Nicely put Chris,
The technique doesn’t end with iconograhpy.
I started redevelopment of my own site and this time it’s quite graphically intensive.
I used the sprite technigue on the complex background and was shocked at the difference.
http://websemantics.co.uk/new/
In Firefox right click on the page background then view the background image.
Click the image to zoom to full size and you’ll see all the background gradients stacked vertically.
It’s also worth noting it’s a compressed .png so there is no image quality loss.
Page load speed, both actual and percieved, is incredible in comparision to the previous trials.
This technique, while problematic and time consuming, is most certainly worth it.
regards
mike
Nice work Mike. Good example of using the sprite technique for different purposes. I would think that if someone where extremely dedicated, you could make an entire complex layout with a single image.
Chris
I’m actually trying to do exactly this. Thankfully it’s not a large image, but I’m only using one image to change between states when the user clicks on buttons overlayed on the image. It’s more complicated than I had hoped.
seekingalpha.com has built its ENTIRE SITE using css sprites.
you can really learn from it greatly !
This somehow sounds like HTTP needs an overhaul – and this suggestion is a workaround.
Not really a workaround. HTTP will never be “overhauled”. What this technique does is streamline/optimize.
Optimization isn’t workaround any more than code refactoring is!
Thanks for putting this comparison together, it really illustrates the size and speed improvements that can be achieved with a little extra planning and work.
I use this technique all the time and love it. The only drawback I’ve found is when printing a page in Firefox with sprites, the full image (all states) is compressed into the “masked” area on the printed document. The print preview looks fine, but the pdf/printed output compresses the image. Seems to print OK in IE.
well I think if you give background-position in Percentages, it certainly breaks or shows different in IE-6 than other browsers..Other shows the position as expected..so in such case you need to give the position in Pixels..Do you think is this is the way it is Or i am going wrong else where? let me know
I like the idea of using sprites (especially for the navigation), however a question has arisen from the Vid tutorial that you did Chris. To offset the nav text you used a negative margin…how do you get around this negative margin when a user has images turned off on their browsers. Yes i know that this isn’t that great an issue with todays bandwiths but it still leaves me wondering as the text will not be on show (if for example the nav is on a banner at the top of a website). Thanks for any answers given to this.
@Nodster:
There are a great number of ways of handling this besides the text-indent method, which does indeed fail with images turned off.
I’d just like to add that I’m using css sprites on my weblog’s current design. Since it’s a PNG-file I decided to kill some of the graphics for IE6 and older browsers, but it works like a charm for all other browsers.
For now the logo is a part of the sprite, but I’ll cut it out and place an
img
-tag at the top div, so it’ll be visible for print too.thank you for your help…sprite111
sj
I think css sprites are an interesting concept, and possibly well suited for a couple applications like backgrounds and basic button rollovers. However, in a production environment where you have one team prototyping and then handing off to a development team (or handing to a client), it really isn’t practical.
Just the issues of color integrity, ease of updating, printing problems, no alt-tag support, etc, are reasons enough to not put this into wide practice on a client’s production site.
While I think I’m getting this gist of this, showing the image you used would help a lot more!
Check out a video podcast example of creating CSS sprites (if you like that sorta thing) here
Hi please, can you help me, css sprites are very interesting, but do they work in internet explorer 6 ??? I have a problem with this..please help, thank’s
I use this method often, but does anyone know why ie6 decides to “reload” the image every time there is a hover?
When you hover over the link the already loaded image, disappears then reloads, E-V-E-R-Y single time!!!!
I heart IE…… not!
Hello,
I created a CSS Sprite Generator in PHP (CLI Mode)
It has the ability to replace the background-Images automatically.
If you are Interested habe a look here:
http://tanila.de/smartsprite/index.php
kind regards
tanila
Hi,
Thanks for your topic, it helped me to works with CSS Sprites!
Here is my wired situation:
I use a large number of css background image (actually 66 images!) for my site. A good percent of these images are used in boxes demonstrations, I can use css sprites trick for left-top & left-bottom corner of boxes, but it seems that there is no way to use in right-top, right-bottom and middles (that must have repeat). Am I mistaken and some how there is some way to achieve this goal?
if there is no way to use this trick, what’s your suggestion to reduce number of images?
I’ll be very grateful to have any ans/suggestion sent to my mail: pashaie-at-gmail-dot-com ;)
Thanks in advance
Perfect! This is just what I need to squeeze out a bit more performance!
Thank you.
Thank you Chris for all your teachings!! Totally Invaluable!! I taught myself ‘sprite navigation’ through your posts and videos and it works great. I have two quarks though… 1.) by moving the text ‘offscreen’ FireFox creates an UGLY dotted box all the way offscreen (used to keyboard navigation). I learned to ‘turn it off’ (outline: 0;) but then… it’s… well, off and difficult for those with accessabiltiy handicaps can’t navigate… Is there a way to just ‘make the text dissapear’ but leave it in position?? 2.) Centering… holy cow… I just spent 4 hours searching the net trying to center the list in my web… no go… I just went for a ‘hack’ to put a left margin on it… Is there a way to center this list?
Where is the link to the css sprite generator?
http://spritegen.website-performance.org/
@Lucy Now that you can zoom in the most browsers. Designers should be creating static font sizes instead of “em” font sizes, so that you don’t have the background image problem.
@Brent People who are tabbing hyperlinks should be using their own CSS or disabling all CSS.
I prefer a middle of the road approach that only creates sprites for the same button. I really hate aligning sprites perfectly, so I’ve created a Photoshop Script that combines two images of the same size to make a simple normal/hover sprite. It’s not as genius as the 20 image sprites you can make online, but it’s much simpler and you can assign a keyboard shortcut to it in Photoshop. I prefer the control of it, and you don’t run into the “I don’t have the source files” problem.
http://www.smjdesign.com/designwell/archives/photoshop-script-combine-two-images-css-hover-css-sprite/
Also, does anyone know if you have to re-create/submit files to these online sprite generators, do the files have to be in the same order by their file name, so that they are in the same place and you don’t have to change all of your CSS rules. Seems like that would be a pain to do.
Thanks a bunch for the script! A definite time saver!
I think that I am going to make an effort to start using this. The only issues that I have is: what if you finish your sprite, everything is perfect but you forget something, something that would require you to redo the entire thing… Then you need to start over, and spend unnecessary time that could be used for something bigger and better.
You don’t redo it, you open up your sprite graphic, make it a little taller or wider and drop the new sprite in there and resave it. It’s definitely more work than using individual images but isn’t the end of the world.
Nice article.. I have been using sprites recently and it really effects the page load speed of the website. If we use single images for menu elements and their hover state then while the site is loading, if we scroll over the menu element, then no image is displayed till it’s loaded properly.. Using css sprites voids this problem.
Yep, quicker transitions is a huge benefit.
I noticed this similar technique used on the play.com website quite a long time ago, but never attempted to try it myself.
This is a nice article, I’m gonna give it a go on a test case and see how it goes.
Nice article Chris, I am a hugeeee fan of css-sprites. I mean check out my sheet for alittlephotoshop.com :
http://bit.ly/4g4Ncr
As you said however, the problem is definitely workflow. I recently had to replace the sidebar header images because I was adding a new one. While being on my laptop I had no PSD, so some serious photoshop hack work started. It’s a massive pain.
Furthermore when you have build your stylesheet on explicit pixel positions, and a graphic then becomes redundant in your site, like in mine the search box was never used. There is basically no way to remove it from the sheet save from recoding the entire thing to prevent file bloat.
Ultimately, how wonderful a service spriteme is ! I think this will be the last time i hand build sprite sheets. Rather, just build the entire site regularly, upload it, run spriteme and finally save a second version of the stylesheet.
Making changes to the original and rebuilding with spriteme seems like the most elegant solution rather than hacking up my sheet time and time again to make minor changes.
You really have a great way of simplifying the this process. It really helped to understand. As others have said, I think planning where you’re going to use them is the most important thing to consider.
Hey Chris,
What is the best way to integrate Sprites into a WordPress CMS site, so that the PHP generated content plays well with the Sprites? Any suggestions…?
-Murph
P.S. – Thanks for the great, informative work you do. I learn something new from one of your sites everyday.
The technique will be exactly the same; WP doesn’t do any magic. The only trick sometimes is identifying where the style is being declared if not in stylesheet.css. Some plugins include their own stylesheets, for example.
Firebug (Firefox) or Dragonfly (Opera) can be handy here.
Once you’ve identifies where the css is, you will simultaneously be identifying the source of the images. If they’re separate images, you just need to open them up in your image editor and copy/paste them into your new sprite file and calculate the offsets.
Greg
Thanks, Greg. Think I’ll give this sprites thing a shot in my next design!
This is one of my most favorite things about CSS. I managed to reduce my template to just 3 images since there’s always all these scripts and other files that like slowing down my site.
Some say that managing sprites is hard, but I think the exact opposite, especially for hovers. Having all those images in one file helps it easier to organize and find them later to edit. Say I’m looking for something in the header, well if you have some sort of “header.png” file, you have your nav and everything in there just like you might have a folder/directory on your server.
I’m against services like SpriteMe, because it’s more of a static solution. If you’re constantly editing your images or find yourself changing your site a lot design wise, you will need to sprite up all the files again and maybe even change the css just for one small change.
Oh and for those who think it’s just not worth it even speed wise, take my header sprite for example. If all those were single images, it’d take forever for my site to load. I don’t have problems editing it either, so that’s a personal issue.
http://cdn.myunv.com/img/resource/sitewide/assets.sprite.png
Sorry for the double post :(
http://www.jaredhirsch.com/coolrunnings/public_images/2593af8d3b/spriteme1.png
Nice roundup Chris! I’m not new to sprites, but I liked how you mentioned what they can’t do (repeating images) and showed some examples from well-known sites.
I’ve found that Mint has some large image sprites for its icon sets.
You can do repeating graphics as long as they go only in one direction (repeat-x or repeat-y).
If you have other images within that sprite that are larger than your gradient, you would simply stretch it to fill the whole width or height.
Good post, I’ve been using sprites for navigations and buttons for a while. I’ve been hesitant to use much larger sprites, with many graphics in one file because of my fear it will slow down the rendering of the page. Even though you can’t “see” the rest of the sprite image, you could have a bunch of 1000px x 1000px sprite files all over your page. Are there any studies showing if this hurts rendering performance? Am I just being paranoid?
Great article on CSS sprites, I found the tips very useful as a newbie to CSS!
Brilliantly written article as ever.
I’ve been aware of sprites for a while now but never really had the urge or justification to start using them. Part of my dubiousness towards them comes from file management and the aforementioned editability (is that a word?!) implications. The idea of “[opening] up your sprite graphic, make it a little taller or wider and drop the new sprite in there and resave it” makes my overly anal organisational tweak rear its head.
Also as someone who does a lot of work fiddling with pre-written Joomla plugins and the like, the idea of not being able to investigate an element, see its background image, create a new one (potentially of a completely different size), upload and replace in favour of sifting through a png image and bloating it with new sprites seems a bit impractical. Obviously it’s a small point in a large discussion but it’s a definite no no for open source developers…
Excellent idea to update and republish this article.
OMG, I am getting addicted to the CSS-TRICKS.com. I was worrying that CSS and other these stuffs like Sprites will be very advanced and hard to understand, But the way you explained made the fear to vanish and I can understand it fully.
Check out Mashable.com they’ve got a pretty slick CSS sprite goin’ on
Mashable Sprite
Great article. I myself use web developer toolbar to check the images other sites use and I’ve seen this many times. I figured it revolved around positioning a single image. I never understood the concept of it more clearly before reading this article. I’ll be sure to implement this in my blog design.
Good Article. Love the bookmarklet, very cool.
Personally I wouldn’t want to sprite all my background images as it would just make maintaining a site problematic. Especially in situations where you might want to change the size of an element and thus the size of the background image – then you would have to rebuild your sprite image AND go through and fix the positioning on many elements. Which brings me to the work around I used on the one site I used this for, just give each item plenty of space so that resizing any given element doesn’t need to effect anything else. (ask.com’s sprite is setup this way, for the most part).
One thing that I didn’t see mentioned (maybe because everyone already knows it). Is that for rollover items this is kind of a must. Without using some form of sprite technique for rollovers, all too often rollovers don’t work properly the first time a user mouses over them. Unless you preload the graphics there will be a delay before the rollover image appears. Users don’t care to wait around for your half loaded navigation system to finish loading when they go to use it..
Oh yeah, I didn’t read all the comments (only about half), but someone mentioned the fireworks’ PNG8 format and its 4 bit transparency and you asked for more info on this but the responses were not very detailed.
I prefer to use fireworks PNG8 for transparent images because they will work in virtually all browsers and while you won’t get alpha trans in IE6 they at least degrade nicely.
I create my image in photoshop and I make sure that any semi trasparent elements are truly semi transparent. Meaning I make sure that shadows have no portion which is more 100% and I amke sure that things which have anti-aliasing first have a clean looking non-anti-aliased version and the anti-aliasing effect is separate and has no portion which is 100% opaque. I do this by breaking things up into layers and then setting the opacity on layers with shadows/anti-aliasing/other semi-transparent effects to 98%. This way I know exactly what will disappear in IE6. Then I open the photoshop file in fireworks and export it as PNG8 with alpha transparency. I tried using some other PNG tools which can convert PNG24s into this format but the results where often very unpredictable and uncontrollable. Fireworks is the only tool which can do this in a precisely manner.
With this type of PNG8 IE6 will show any pixel which is less than 100% as 0% so it will basically display as a regular PNG8 with 1 bit trans. So all the shadows/anti-aliasing/etc. simply disappear in IE6. So you get some more jagged images with no shadows etc.. But at least you don’t get big gray boxes and you don’t need to use any PNG transparency fixes either. I have tried many PNG trans fixes (maybe even all of them) but generally I have found them all to be problematic and/or unreliable, meaning it may seem to be working fine in IE6 but then I see it on a friends computer with IE6 and it is all half broken for some reason. I also prefer to avoid js for style/appearance and only use it for functionality. So you can see the site fine without java but if you want to use some feature maybe you will need js.
As far as things looking a little jagged in IE6.. Personally, I couldn’t care less as long as the layout isn’t broken and there aren’t big gray boxes all over.
A word of warning though: this technique is best used by people who are well versed in photoshop and who have a strong grasp of raster based graphics in general, because without taking deliberate and precise control of transparency levels in your graphics the results may be very unpredictable and ugly.
A word of advice: I was working with raster graphics for game mods for doom/doom2 and the marathon games back in the 90s and those games only supported 1 bit transparency. Also icons for win95/98 could only have 1 bit trans. If you get right in close and carefully tweak the edge pixels by hand you can create fairly clean looking edges and minimize the jagged appearance of 1 bit trans graphics. But I have yet to see any app that will do a good job of this automatically. If you import an illustrator file in photoshop and turn off anti-aliasing in the in the import options you will get a very nasty looking jagged image but if you spend an hour or two tweaking the edge pixels you can make it look quite clean. Of course semi-transparent or specific background color anti-aliasing will look cleaner still but by combining all of this in a carefully controlled manner we can use semi-transparent PNGs that degrade very nicely in IE6 (i think even 5.5) without messing with javascript fixes or AlphaLoader (which is very slow).
The problem with most of the PNG fixes are that they mostly depend on JS and AlphaLoader or old VRML features all of which will be more strain on the client system. Yeah sure, no big deal on this system I’m working on now, but the crappy old junker system I use to test IE6 is slowed to a horrible crawl by those fixes and the reason I use that crappy system to test IE6 is that I think it is representative of the type of system that most people who are using IE6 may have.
You can find other tutorials on using PNG8 with 4 bit alpha trans and you can find a couple other tools that can convert PNG24s to this format, but those tutorials don’t go into the various quirks that you will come up against. To get really good results is not as simple as just converting a graphic, but if you put some thought into it and do some experimentation and use fireworks as oposed to one of the other converter tools you can get splendid results this way. Also much smaller files than PNG24. Some graphics just won’t look nice this way though because of the limited color palette which is further reduced by the 4 bit alpha, large gradient areas for instance.
I freakin love the Chuck Norris quote – good form!
I’m new to CSS, so please bear with me.
I can get the background image to load correctly by putting it in a class definition, like this:
.item-video {
background-image: url(‘images/video-nav.gif’);
}
… but only if I then apply the class to the li element. The gif does not appear if I apply the class to the anchor element. And when I do get the gif to appear when applying the class to the li element, the href link in the anchor does not work.
I think this is because the li and a HTML elements really don’t have any content… just a background graphic, so I’m a little lost. It seems like in Chris’ “after” example above, he has the Item 1, Item 2, Item 3, etc, text elements in the anchor elements, but what’s creating the actual box around the text and background element for the browser to “see” as a link?
Any help is much appreciated.
Sprites are cool but I wanted to have more control about how I create them, I tried an Air App called Tonttu but I can’t export anything from it, if I could it would be perfect.
Has anyone used it with success or shall I just not bother with it?
Tonttu worked very well actually. Though, I think Spriteme takes into account your css quite a bit more making it the better option of the two.
Hi Zander,
Try spriteme.org straightaway it is very better.
Great post! I was wondering if it was faster to do something like this, and come to find out, it’s way better and faster! Thanks for the tips!
Yeah, I always used to wonder about how they work. Very good explanation by the author. Its really good and fast if we can split simply a single image for various objects.
Best Regards
I think is good idea, but I hadn’t try it out sometimes!
I never thought quoting Chuck could be so profound.
Great article,… and a good way to optimize a site.
Good article! What do you think if all images will be in one sprite, and the sprite image will be big (width x height), and used for around 50 elements, won’t that be slow for some browsers?
Thanks.
I have been heard and even trying to use sprites on my websites but I never taught it can be so global implemented. Thanks for the article. Bookmarked :)
I don’t know if someone already posted this suggestion but wouldn’t it be faster for the site to load if the buttons would be split into 3 layers: normal background, hover background and button image. You’re loading normal bcg and hover bcg just once(2 HTTP requests) and then button images(5 HTTP requests). That gives 7 HTTP requests and the images should be really small in size.
What do you think about this idea?
Good idea, thank you for your interesting article.
I just heard about sprites from the good folks at welovecss.com. I wanted to use something besides javascript and though this is stretching my capabilities a bit which is good, I love it!
Thanks for a great informative article.
i was always viewing simlies of facebook and google(1st time i seen there). i was thinking how do they do. :o its pritty easy. :p
It’s a great and helpful article. Thanks for sharing with us.
All the best.
I created an application for Mac called Sprite Master Web to help devs to create spritesheets and CSS code automatically.
You can find it at mobinodo.com/spritemasterweb
Hi Chris, Finally I got, what exactly CSS sprite means. Thanks!
great revamped article!
I’ve just taken over a project using sprites extensively. The following tool helped to lessen the pain of updating some icon even in size:
http://www.spritecow.com
A different way to do this is to just create textNodes or an empty element instead of creating a transparent image. That way you’re only using one image, the spritesheet.
I’d prefer using this method over textnodes, just easier
Any way to do this using SVGs?
http://www.smashingmagazine.com/2014/03/05/rethinking-responsive-svg/
Really helpful article.
I am looking for something like this, but I also want to position the background image on the right center of the UL LI. The image is not the same width and height as the UL LI i use it in as a background (icon).
So I would need to use: background-position: right center; but then I cannot use it to position the sprite and it shows the whole sprite img.
Great post! We are using sprites for big directories and they work very good. The most important thing is that it reduces a lot the calls to server – for desktops or mobile – it just shows instantly a raise in the load time. But it is of course if you optimize the whole sprite image. Other than that sprites is the greatest invention from css – in my opinion, ;)
Can’t wait for SVG to be widely supported and optimized for web performance. CSS sprites go a long way for eliminating HTTP requests but nowadays we need our icons in many dimensions for responsive websites and for devices with higher pixel density (Retina). So, vector is the next logical step in evolution.
The site I am working on has recently been suffering from slowish loading, mainly down to my code and images not being as optimised as they could be :)
I have added a page which needed quite a few images, but wanted to ensure the load speed was not overly affected. Read about sprites a while ago and just by chance a quick search led me here. Wow! Opened my eyes somewhat. I have implemented the technique here PIL Leaflets and it works a treat.
One slight adaption is I wanted a common background which I have added via css to the containing div, the sprites are applied to the img itself which overlays this. This keeps the main sprite to a minimum size. Over my old methods of working, I reckon its saved 4-6 secs on the load time. I’m sure with some tweaking it can be reduced even further.
And was quite fun putting it together to boot! Cheers for the article, it was a great help :)