WEB Advent 2012 / Retina Ready

When you get your shiny new retina device this holiday season, will the Internet be ready for you to see all its content in twice the pixel density glory? Probably not. But, this handy guide will help get your site “retina ready” in no time.

Pixel density? Retina ready? Say what?

Many new mobile devices are built using special display panels that are capable of displaying more pixels per inch than the standard display you’re probably used to. For Apple products (iPhones, iPads, &c.), the density is twice as many pixels as usual. Android device pixel density can range from 1.3 to 2 times as many. When you view an image on a high pixel density device, it is doubled in width and height to compensate for the smaller pixels, meaning your image only has 1 pixel to fill for every 2 (or so) on the screen. This is why “1x” images look blocky on high pixel density displays. One of the fastest and easiest ways to improve the look of a website on retina displays is to offer a “2x” version of every image, so the pixels fill up natively and without up-sampling.

Here’s an example showing a 1x image (left) and the 2x version (right):

How do I make my web site retina ready?

Compass, a framework for the CSS pre-processor Sass, has built-in image functions that will build 1x and 2x assets for your web site with just a couple lines of code. By specifying the location of a folder full of images, Compass can stitch them together into a single sprite and provide you with all the CSS classes, background positions, and pixel dimensions you need to start using your sprite right away.

The first step is getting all the individual images. To be “retina ready”, you’ll need the regular versions of all your images as well as one twice as big as the original (the 2x version). The method works by displaying the 2x sprite only on retina devices and CSS-resizing it back down to its 1x dimensions. That way your image fits into your design the same way it did originally, but all the extra pixels are there for your device to use to display a sharp picture. A tool like Slicy will make exporting multiple images from Photoshop a snap, and even automatically generate 2x versions of vectors and layer styles for you.

Once you’ve got all your images, just split them into two folders, one for the standard 1x images and a second for the 2x images:


Next, you’re ready to start coding. Just a few lines of Sass will get you everything you need:

$icons-layout: smart;
$icons-2x-layout: smart;

$icons-sprite-dimensions: true;

@import "icons/*.png";
@import "icons-2x/*.png";

@include all-icons-sprites;

Let’s break this code down:

  1. Lines 1 and 2 tell Compass how to lay out the images in both the 1x (icons) and 2x (icons-2x) sprite. “Smart” mode arranges the images in the least amount of space possible. We want both sprites to use the same layout mode.
  2. Line 3 line tells Compass that we are going to want the generated CSS to include the dimensions of each image.
  3. Lines 4 and 5 tell Compass to build a sprite using the PNG files in the imported directory.
  4. Line 6 tells Compass to generate the CSS for the 1x sprite.

Once you compile your Sass file, you should see two new images appear (your sprite files) and one new CSS file containing all the class names (based off the image file names), background positions, and dimensions of each image in the sprite. Your sprite is 100% ready to go; just apply one of the class names to an element in your markup, and your image will appear. How easy was that‽

Here are the 1x and 2x sprites:

If you’re wondering why we didn’t also generate CSS for the 2x sprite, think back to how we said we would CSS resize it down to fit into its original 1x dimensions: because both sprites are laid out identically, we can let the CSS-downsized 2x sprite rely on the background-positions and dimensions of the 1x sprite. The last step is to simply add CSS to swap out the file path and CSS downsize the sprite when on a retina display:

@media (min--moz-device-pixel-ratio: 1.3),
       (-o-min-device-pixel-ratio: 2.6/2),
       (-webkit-min-device-pixel-ratio: 1.3),
       (min-device-pixel-ratio: 1.3) {
    .icon {
        background-image: sprite-path($icons-2x-sprites);
        background-size: image-width(sprite-path($icons-sprites)) image-height(sprite-path($icons-sprites));

That’s it! The browser will now serve up the 2x sprite in place of the 1x on high pixel density devices, and your web site will look sharper than ever when you view it on your new iPad 4 (or iPhone 5, or Galaxy Note II, or Nexus 10, or…) this holiday season. Happy browsing!

Other posts