At one time or another, you may have found yourself wanting to use sprites in your responsive website design. While at first this may seem like a very simple task, in reality it’s a little more difficult of a challenge. It can, however, be done. Here’s how! This trick is fully supported by all modern browsers other than IE 8 and earlier, in which the image resizing aspect will not work properly, though it will not break completely.
Let’s start with our HTML. Let’s say we have part of a website here, and what we want is for the background image of this div to change when we hover over it. The catch is that we are using a sprite for it (a single image containing both our normal and rollover images) and it’s a responsive design. Let’s take a look.
Okay, the html isn’t really that relevant I realize now. I could make it more fancy to try to make it a “real world example,” but why bother? Keep it simple, stupid.
The secret is clearly all in the css. Let’s say this div is always a square, using our trick to maintain the same aspect ratio for an element in a responsive design. This might be the CSS of the element before we’ve added the background image.
Now we have a square image we want to nestle nicely inside there. And when we rollover the element, we want it to change. How do we do that? By adding the following css:
background-position: 0 0;
Now here’s what’s really interesting about the background-size property. It does not STRETCH the image in both directions, it assumes that the image fits perfectly WIDTH-wise into our container, and then calls that 100%. If we want the image to be larger than what actually fits in the container, we go bigger. If we want it to be smaller and have to repeat, we go smaller. In our case, let’s say our image is 1000px wide and 500px tall. On the left 500px we have the first image, on the right 500px we have the rollover image. If we were to leave the setting at background-size: 100%;, we would end up with the image fitting completely within the div and repeating itself once underneath.
We don’t want this, however. We want the first half of the image only to fit. So we set background-size: 200%;, since we need it to be twice as large as the space we have assigned for it, since we only want the first half of the image to fit in our div.
Now it’s time to set everything up for the hover state. To do that, we add this to our css:
background-position: 100% 0; /* Use ONLY percents here */
The only thing we need to change is the background position! The secret is to place the background image using only percents. This is what allows it to be responsive. Actually USING this positioning system can be a little confusing, so let me break it down for you.
Calculating the background position
This is actually quite complicated and not at all intuitive. The best way I can explain it in words is this: the distance between 0% and 100% for your background position is the distance between when the left edge of your background image is touching the left edge of your element, and when the right edge of your background image is touching the right edge of your element.
So let’s break this down into a formula I came up with. This formula assumes each image in the sprite is the same size, and that each image is the same size as the element (i.e.: fits it exactly).
Percent Increments to Use = 100% / (Discrete images in your sprite – 1)
So if you have 4 images in your sprite: 100% / (4-1) = 100% / (3) = 33.33333%
So to display the first image, you set background-position: 0 0;. The second, background-position: 33.33333% 0;. And so on. Again, it’s not that intuitive, but with the formula it’s a little easier.
Let’s Consider another example. You have FIVE images in one sprite that you wish to use, all in a row. You want to display the SECOND image in the row. What background position do you use? Well… 100% / (5-1) = 25%. So if I wanted to display the second image, I would have to use background-position: 25% 0;. Easy!
If you would like to see a real-life and real-creepy example I made using my own face, check it out here!