Retina Sprites

A sprite is simply an image that has many images in it like this. (I’ve put it on a black background so it shows up better.)

sprite_example

Obviously we can’t call an image like this normally, we have to use background images on a div with a set size like this:

<div id="mysprite-example"></div>

#mysprite-example {
  width: 60px;
  height: 60px;
  background-image: url('sprite.png');
  background-repeat: no-repeat;
  background-position: -60px -170px;
  display: inline-block;
}

The above HTML and CSS would look like this:
sprite_example_1

So, we’re defining a set area, setting the background image, then moving the background image around in order to place it correctly.

For retina screens

That’s great, but the above image looks awful on an iPhone or any retina screen because the pixels are doubled up, making this image look fuzzy. Don’t worry, there’s an easy fix! When I’m doing sprites, I make sure that the Photoshop file only has smart objects in it, meaning that the layers are vector and can be scaled up. Whatever size the sprite image ends up being, double the image size. For example, our sprite image is 218px X 290px. So, for retina, we want it to be 436px X 580px. Let’s try that out with a media query to switch out the background image for retina devices.

<div id="mysprite-example"></div>

#mysprite-example {
  width: 60px;
  height: 60px;
  background-image: url('sprite.png');
  @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { 
    background-image: url('sprite@2x.png');
  }
  background-repeat: no-repeat;
  background-position: -60px -170px;
  display: inline-block;
}

Now, this is how the above code would look on a normal screen and a retina screen respectively.

sprite_example_1

sprite_example_2

Wait, something’s not right on that second one. It seems like the background image is the correct one being used, but it’s way bigger than it should be relative to our 60X60 div. No worries, there’s an easy fix. Simply define the background size for your sprite to use the image size of your original sprite and all will be well.

<div id="mysprite-example"></div>

#mysprite-example {
  width: 60px;
  height: 60px;
  background-image: url('sprite.png');
  @media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) { 
    background-image: url('sprite@2x.png');
  }
  background-repeat: no-repeat;
  background-position: -60px -170px;
  background-size: 218px 290px;
  display: inline-block;
}

The above code will result in the desired effect. Let me know if you have questions!

Lars Miller

Lars is a front-end and WordPress developer.