Home > css, dev, Mobile, open source > iOS Retina Sprites

iOS Retina Sprites

One of the great things about the iPhone 4 is the Retina Display. Native iOS apps make handling the switching between the non-retina and retina version of the image really easy. Simply supply the two files and suffix one with “@2x” and it handles the rest (ex: 1.png, 2@2x.png). Taking advantage of the retina display in a web app is not so easy, especially if you want to use sprites.

This example will assume that you have three images that you wish to turn into a sprite that will support both retina and non-retina displays.

Create Images

Retina images are basically twice the size of the non-retina version which is then rendered into the non-retina dimensions to double the DPI. This means that if you want a retina and non-retina version of an image you should start out with the retina version (lets say, 50px x 50px) and then generate your scaled down version at 50% (25px x 25px).

In our example we will have three images: a, b and c. These images are to be shown at 56px x 22px on the screen. This means that our retina version will need to be 112px x 44px and our non-retina version should be 56px x 22px. Once you have the retina and non-retina version of all three images (you should have six images total) you’ll want to create a zip file for the retina images and a zip file for the non-retina images.

Generate Sprites

There are a lot of useful services and tools that will generate your sprites for you. For this example we are going to be using the CSS Sprite Generator service at http://spritegen.website-performance.org/.

The settings between retina and non-retina are going to be slightly different so pay close attention to the different settings.

Generating Non-Retina Sprite:

  1. Select your zip file, be sure to pick the non-retina zip.
  2. Under “Sprite Output Options” > “Build Direction” choose “Horizontal”.
  3. Under “Sprite Output Options” > “Horizontal Offset” enter “25px”.
  4. Click “Create Sprite Image & CSS”

Save the outputted file as “test-sprite.png” and copy the generated CSS to a temporary file, we’ll come back to it momentarily.

Generating Retina Sprite:

  1. Select your zip file, be sure to pick the retina zip.
  2. Under “Sprite Output Options” > “Build Direction” choose “Horizontal”.
  3. Under “Sprite Output Options” > “Horizontal Offset” enter “50px”.
  4. Click “Create Sprite Image & CSS”

Save the outputted file as “test-sprite@2x.png”, you can ignore the CSS generated.

You probably notice that the only main difference between generating the retina and non-retina sprites was the horizontal offset. Basically we are going to have web kit scale our retina version by 50% so we want the offsets between the images in the sprite to remain the same. This means that the horizontal offset between the images will need to be doubled in the retina sprite, just like the images themselves.

Generate CSS/HTML

Unfortunately we aren’t so much generating CSS as we are piecing together some previously generated CSS.

Sample HTML

Here’s the HTML that we’re going to be styling:

<div class=”test-sprite” id=”a”></div>
<div class=”test-sprite” id=”b”></div>
<div class=”test-sprite” id=”c”></div>

Base CSS

Let’s define the test class which will be where we handle setting our default sprite properties (non-retina):

	background-image: url(images/test-sprite.png);

Take note of the width and height, it’s the size of the non-retina images. When we insert our retina version the browser will handle scaling them down to fit the correct dimensions. Now we need to specify our retina sprite, we do this via a CSS override of the previous class’ background image. The override is handling using CSS3 Media Selectors:

@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
       only screen and (min--moz-device-pixel-ratio: 1.5),
       only screen and (min-resolution: 240dpi) {
			background-image: url(images/test-sprite@2x.png);
			-moz-background-size: 218px 22px;
			-o-background-size: 218px 22px;
			-webkit-background-size: 218px 22px;
			background-size: 218px 22px;

Here you can see we overrode the background image with our retina version as well as specified a background size. If you pay close attention you’ll notice that the dimensions do not match those of the image, but rather those of the non-retina image – this is where we utilize the browser to handle our retina scaling.


Now its time to create our sprite classes, this is the easy part. You’ll need to reference the generated sprite CSS from the non-retina, it’s very important that you use the offsets provided by it rather then the retina version. All you care about is the background-position variable, the rest you’ll fill in yourself:

#a{ background-position: 0 50%; }
#b{ background-position: -81px 50% }
#c{ background-position: -162px 50% }

That was the easy part, just a simple background position offset with a 50% horizontal/vertical offset.

  1. November 24, 2011 at 10:23 am

    Shouldn’t the dimensions in the second block of CSS be 112×44, not 218×22?

    • February 4, 2012 at 11:43 pm

      yea, they should be the size of the non-retina image.

  2. February 4, 2012 at 11:43 pm

    Thanks Dude. Up too late trying to figure this out. Kept trying to use percents. Didn’t work. 😉

    Pixels, pixels, pixels. ;

  3. Adrian
    June 19, 2012 at 4:00 pm

    This does not work. I followed instructions to a TEE and the images do not show properly on an iphone. This is the code:


    .social-icon {
    background-image: url(../images/social-sprite.png);

    @media only screen and (-webkit-min-device-pixel-ratio: 1.5),
    only screen and (-o-min-device-pixel-ratio: 3/2),
    only screen and (min–moz-device-pixel-ratio: 1.5),
    only screen and (min-device-pixel-ratio: 1.5),
    only screen and (min-resolution: 240dpi) {
    .social-icon {background-image: url(../images/social-sprite@2x.png);
    -moz-background-size:235px 40px;
    -o-background-size:235px 40px;
    -webkit-background-size:235px 40px;
    background-size:235px 40px;

    (original sprite image is 235×40 – @2x sprite is double that… 470 x 80)

    #facebook{ background-position: 0 0; }
    #linkedin{ background-position: -65px 0; }

    HTML code is an ID given to an image like so:

    Doesn’t work…

  4. September 20, 2014 at 2:26 pm

    Thanks for one’s marvelous posting! I actually enjoyed reading it, you might be a great author.
    I will be sure to bookmark your blog and may come back in the foreseeable future.
    I want to encourage yourself to continue your great work, have a nice evening!

  1. April 28, 2012 at 8:18 pm
  2. April 29, 2012 at 12:00 am

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: