Retina Quickie

After reading Marco Arment’s The Retina War[^marco] and John Gruber’s Pixel Perfect, like me, you’ll probably want to upgrade your web graphics so they’ll look great now and on future devices.

So, if you’ve got some web content that you want to retinafy, here are some quick notes on what to do based on the type of content.

Text

You’re done. Nothing to do here except give your site a visual check to see what your current fonts look like. Some typefaces will render differently depending on the weight and current screen optimization. For example, a thin font may look even thinner on a retina display given that it can be more accurately rendered.

Favicon

Create a single ico by taking your existing 16x16 icon and a 32x32 version that has full alpha transparency. You can use the awesome xiconeditor web app to do this.

<canvas>

You’re done. There’s some behind the scenes magic involved but nothing to do here. Move on.

Images

Here’s where it start to get interesting.

SVG

Again, you’re done! Vector images will render in high res as needed.

JPG, GIF, PNG

For pixel based images you’ll need to re-create new versions that are scaled by two (@2x). That means if your image is 100x100, you need to re-create it at 200x200. Hopefully you still have those originals you scaled down! It’s important to remember that you might need to do more than just “scale” the image. Many images will require hand-optimizations and alterations to provide the best sharpness and detail at each resolution. Neven Mrgan has a great post about iOS icon sizes that has tips on the difference between small and large icons.

Next, do yourself a favour and run all your images through ImageOptim to reduce their file size. This isn’t necessary but now that you’re serving even larger images, bandwidth is going to be more of a concern. If your original image was in an <img> element, you could use the new scaled up image along with the original @1x images’s size as the width and height attribute. The disadvantage here is that non-retina devices will still download the higher resolution image. Instead, switch to using a CSS background image and a media query. For CSS backgrounds, you’ll need to add a CSS @media query that targets retina screens using screen and the resolution/ratio properties for the various browsers.

@media 
only screen and (-webkit-min-device-pixel-ratio: 1.5), 
only screen and (-moz-min-device-pixel-ratio: 1.5), 
only screen and (-o-min-device-pixel-ratio: 3/2), 
only screen and (min-device-pixel-ratio: 1.5), 
only screen and (min-resolution: 1.5dppx) {
    /* Put all your retina selectors here */
    .image_selector {
        background-image: url(scaled_image.png);
    }
}

If the image is part of a sprite sheet don’t worry, just include the background-size property to translate the dimensions of the @2x sprite down to the original @1x sizes (for positioning the sprite images).

background-image: url(image@2x.png);
background-size: [@1x width]px [@1x height]px;

Otherwise, for single images, you can use 100% for the size.

background-image: url(image@1x.png);
background-size: 100%;

For example, if you have a 100px square sprite where a 10px square image is located at 20,20 in the original @1x image (making the @2x image 200px square with the 20px square sprite at 40,40) you would have something similar to this:

div.sprite_image {
    width: 10px;
    height: 10px;
    background: url(image@1x.png) no-repeat -10px -10px;
    background-size: 100%;
}

@media 
only screen and (-webkit-min-device-pixel-ratio: 1.5), 
only screen and (-moz-min-device-pixel-ratio: 1.5), 
only screen and (-o-min-device-pixel-ratio: 3/2), 
only screen and (min-device-pixel-ratio: 1.5), 
only screen and (min-resolution: 1.5dppx) {
    div.sprite_image {
        background-image: url(image@2x.png);
        background-size: 100px 100px; /* @1x size */
    } 
}

Now

The post ‘Retina Quickie’ was first published by Jeffrey Sambells on