{"id":158,"date":"2009-10-24T09:41:00","date_gmt":"2009-10-24T16:41:00","guid":{"rendered":"http:\/\/css-tricks.com\/css-sprites-what-they-are-why-theyre-cool-and-how-to-use-them\/"},"modified":"2017-06-27T06:26:28","modified_gmt":"2017-06-27T13:26:28","slug":"css-sprites","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/css-sprites\/","title":{"rendered":"CSS Sprites: What They Are, Why They’re Cool, and How To Use Them"},"content":{"rendered":"

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.<\/em> <\/p>\n

What are CSS Sprites?<\/h3>\n

Spoiler alert: they aren’t fairies that write your stylesheets for you. I wish.<\/strong> 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.<\/p>\n

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<\/a>, dating back to 1975, should help clear things up.<\/p>\n

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. <\/p>\n

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.<\/p>\n

Why use CSS Sprites?<\/h3>\n

It may seem counterintuitive to cram smaller images into a larger image. Wouldn’t larger images take longer to load?<\/p>\n

Let’s look at some numbers on an actual example:<\/p>\n\n\n\n\n\n\n\n
Image<\/th>\nFile Size<\/th>\nDimensions<\/th>\n<\/tr>\n<\/thead>\n
canada.png<\/td>\n1.95KB<\/td>\n256 x 128<\/td>\n<\/tr>\n
usa.png<\/td>\n3.74KB<\/td>\n256 x 135<\/td>\n<\/tr>\n
mexico.png<\/td>\n8.69KB<\/td>\n256 x 147<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n

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.<\/strong> This isn’t a big difference, but there needs to be a good reason to accept this larger file… and there is!<\/strong><\/p>\n

While the total image size (sometimes) goes up with sprites, several images are loaded with a single HTTP request<\/strong>. Browsers limit the number of concurrent requests a site can make and HTTP requests require a bit of handshaking<\/a>.<\/p>\n

Thus, sprites are important for the same reasons<\/a> that minifying and concatinating CSS and JavaScript are important.<\/p>\n

How do you use CSS Sprites?<\/h3>\n

Here’s an example sprite, with three different countries flags combined into a single image:<\/p>\n

<\/figure>\n

You set the same background-image<\/code> 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:<\/p>\n

.flags-canada, .flags-mexico, .flags-usa {\r\n  background-image: url('..\/images\/flags.png');\r\n  background-repeat: no-repeat;\r\n}\r\n\r\n.flags-canada {\r\n  height: 128px;\r\n  background-position: -5px -5px;\r\n}\r\n\r\n.flags-usa {\r\n  height: 135px;\r\n  background-position: -5px -143px;\r\n}\r\n\r\n.flags-mexico {\r\n  height: 147px;\r\n  background-position: -5px -288px;\r\n}<\/code><\/pre>\n

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!<\/p>\n

Generate Sprites with Grunt \/ Gulp \/ Node<\/h3>\n

If you’re using Grunt, Gulp, or Node in general, css-sprite<\/del><\/a> (now called sprity<\/a>)<\/ins> 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<\/a> of those), and stylesheet generation in CSS, LESS, Sass, and Stylus.<\/p>\n

To compile sprites via command line, install css-sprite globally with:<\/p>\n

$ npm install sprity -g<\/code><\/pre>\n

Then, to generate sprites and the corresponding stylesheet, run:<\/p>\n

$ sprity .\/output-directory\/ .\/input-directory\/*.png<\/code><\/pre>\n

For more information on using css-sprite with Grunt or Gulp (or many other environments), head over to the project’s repository on GitHub<\/a>. <\/p>\n

Generate Sprites with Compass<\/h3>\n

Generating sprites with Compass<\/a> takes some additional setup and maintenance, but if you’re already using Compass, it fits in well with your existing workflow.<\/p>\n

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.<\/p>\n

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<\/strong>.<\/p>\n

@import \"compass\/utilities\/sprites\";\r\n@import \"flags\/*.png\";\r\n@include all-flags-sprites;<\/code><\/pre>\n

This is a fairly simple process for generating sprites, but it has a few drawbacks\/oddities:<\/p>\n