CSS Techniques for Retina Displays

Syed Fazle Rahman

As many people use their highly portable devices for work and play, device manufacturers seek to enhance their user experience, making their devices simultaneously more powerful and easier to use.

Apple gave us a completely new line-up of products that introduced double density pixel screens, creating sharper images on smaller screens. Other device manufacturers are following suit with their own version of high pixel density screens.

While this is undoubtedly a boon for consumers and end users, it can present a challenge to web developers and designers to make their websites and apps compatible with such Retina displays.

It was then that web developers realized how old fashioned the web is and how websites looked “non-living” on such displays.

Does this mean websites look broken on such devices?

No, the websites are not broken on Retina devices. They just look fuzzy and pixels start appearing on low resolution images. The overall structure of the website remains same.

Pixels and Screen Density

When we speak about pixels, they are nothing but the smallest physical unit in a display. It is a minute area of illumination which when combined with many other pixels form an image. Each pixel has its own brightness level and colors standard as instructed by the operating system. It is the imperceptible distance between two pixels that makes the image look sharper and bright.

Screen density on the other hand refers to the total number of such pixels that physically appear on a display screen. It is generally measured in pixels per inch format popularly known as PPI.

The term Retina mentioned in the title of this post is a friendly word used by Apple to lay emphasis on the double density pixels screen of its devices. On such high resolution display screens like of Retina Ipad and MacBook Pro, it is nearly impossible for a human eye to see the pixels from a normal viewing distance.

CSS Pixel

CSS pixel is an abstract unit used by the browsers to draw images and other content on a web page. CSS pixels are DIPs which means they are device independent pixels. They readjust themselves according to the pixel density of the screen they are rendered in.

If we have the following piece of code:

<div style=”width:150px; height:200px”></div>

The above HTML component would look 150px by 200px in size in a standard display while 300px by 400px in a Retina display to retain the same physical size.

Pixel Density

Resizing Images

1)      Using alternate high resolution pixels

Suppose we have an image of 200px by 400px (CSS pixels) and we want to display it properly in a Retina display. We can upload an alternate image of size 400px by 800px in our server and render them whenever the webpage is opened in a Retina device.

But to make them appear physically of the same dimensions we have to use CSS to resize them. The following is the piece of code that explains this.

/* for low resolution display */

.image {

    background-image: url(/path/to/my/lowreslogo.png);

    background-size: 200px 300px;

    height: 300px;

    width: 200px;

}

/* for high resolution display */

@media only screen and (min--moz-device-pixel-ratio: 2),

only screen and (-o-min-device-pixel-ratio: 2/1),

only screen and (-webkit-min-device-pixel-ratio: 2),

only screen and (min-device-pixel-ratio: 2) {

.image {

    background: url(/path/to/my/highreslogo.png) no-repeat;

    background-size: 200px 400px;

/* rest of your styles... */

}

}

2)      Using @face-fonts instead of images icon

If you are displaying a large number of icons in your webpage, then resizing each on them with a double resolution icon will be a hectic job. We will try to use @font-faces instead of images. These image fonts will automatically resize themselves on the high resolution devices just like normal fonts do. Using @face-fonts is an alternate solution to Bitmap icons.

Today, there are many good quality icon fonts that can meet your requirements for website design. Examples of such fonts are Fontello and Inkscape.

The following code shows how to use @font-faces as a replacement to image icons:

In HTML:

/* define span tag for letters and give them a class in HTML */

<span class=”myicon”>d</span>

In CSS:

/* First import your font */

@font-family: myFont;

src: url('Modern_Icons.ttf'),

     url('Modern_Icons.eot'); /* IE9 */

. myicon {

    font-family: ‘Modern Icons’;

}

3)      Using SVG images instead of Bitmap images

Bitmap images are raster images that multiply their pixels in Retina displays. But they come with a limitation of getting multiplied infinite number of times. This is where SVG images come to role. They also solve our problem of uploading alternate images of double resolution plus they solve the bandwidth problem too!

In HTML:

<img src="example.svg" width="150" height="200"/>

In CSS:

.image {

    background-image: url(example.svg);

    background-size: 150px 200px;

    height: 150px;

    width: 200px;

}

4)      Using JavaScript to replace all the images with double sized image

As mentioned, replacing low resolution images with double resolution images consumes extra bandwidth and the website will load slowly. Still, if you want to go with the first method as discussed above, then replacing each one of them by writing individual code will be a difficult task.

We can use JavaScript to replace all images in a webpage. The following code explains this.

$(document).ready(function(){

    if (window.devicePixelRatio > 1) {

        var lowresImages = $('img');

 

        images.each(function(i) {

            var lowres = $(this).attr('src');

            var highres = lowres.replace(".", "@2x.");

            $(this).attr('src', highres);

        });

    }

});

The above code assumes that you have named the images with low resolution as myimage.png and high resolution images as myimage@2x.png. It finds the first dot in the image name and replaces it with myimage@2x.

One of the major disadvantages of using the above JavaScript method is that the Retina display device would have to download both versions of images every time the page loads. This will surely affect the loading time of your website.

In my opinion, you must go with vector images method (SVG) as their size is low. For icon images you can use @font-faces method. These two methods will definitely make your website shine and lively in Retina devices.

Working with high resolution favicons

Today favicons are used in multiple purposes both in standard devices as well as Retina displays. Favicons are used as bookmarks on home screen in Apple devices. So they have to be of better quality. You can export both 16px and 32px versions to make a favicon Retina ready. Use Apple’s Icon composer, Graphic Tools in XCode, for a good Retina favicon.

Conclusion

The web is undergoing a transformative phase in which websites are made ready for such Retina displays. This transformation is slow but an effective approach to make visitors happy with the content.

As web designers we have to use the above CSS techniques to make websites ready for high resolution display screens.

And if you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like HTML5 & CSS3 For the Real World.

Comments on this article are closed. Have a question about CSS? Why not ask it on our forums?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Sergey

    There is another approach. For example you have highres image with initial dimensions – 400 x 200 and need to display image with size 200 x 100 on your page. Only you have to do is to shrink down the width and height in an img tag –
    The disadvantage of this approach is necessity to load fullsize image even for the nonretina displays.

    • Tomas

      And another disadvantage of this approach is that you force browser recalculate image.

  • http://www.alecrust.com/ Alec Rust

    Nice article. One thing to mention – you don’t need a 32×32 and a 16×16 favicon, just the 32×32 on its own. There are no issues with the 32×32 version being scaled down on older browsers. Details here: https://github.com/h5bp/html5-boilerplate/issues/1285

    • http://www.extremecss.com/ Syed Fazle Rahman

      Thanks Alec. :)

  • Bas

    Excellent article!

    About step 4. Maybe you can prevent the double loading like this.

    Set a cookie asap (in the header) when first loading the page that holds the image enlargement factor that should be used (2 in this case). Before loading anyhing else. Then have an apache rewritecond that checks the cookie and appends @2x instead of javascript.

    • http://www.extremecss.com/ Syed Fazle Rahman

      Hi Bas,

      Thanks for the suggestion. :)

  • http://www.gonzoblog.nl Gonzo the Great

    Hi Syed,

    great article, .. altho, I’m reading the same techniques over and over again, but all posts seem to miss one of the best and most easy solutions for Retina images?

    Double-sized images WITH image compression is imho as easy as pie, 2 great benefits: always load 1 image (no extra CSS, JS or jQuery – no bloated CSS code, no extra HTTP-requests, etc.) and you’ll save even more bandwith when you compress your images!

    JPG compression saves you ‘tons’ of bytes, PNG/GIF compression also minimizes file size of these formats, but not as much as JPG compression. For more info, please read: http://blog.netvlies.nl/design-interactie/retina-revolution/ and http://retinafy.me/jpgs/

    • http://www.extremecss.com/ Syed Fazle Rahman

      Thanks for the suggestion. :)

  • http://www.moreonfew.com Tiji

    Syed, I must appreciate your efforts in putting up the article and making that extra efforts by using images to explain. Thanks. :)

    • http://www.extremecss.com/ Syed Fazle Rahman

      Thanks for liking the article. :)

  • http://www.daddyfinland.fi Jarno marttila

    You should try this free script called adaptiveimages. It’s a apache, php and cookie combination, working just great…

    http://adaptive-images.com/

  • Dave

    I think they forgot to do a spell check before publishing this page.
    “high pixel desnity screens?”

    • http://www.onsman.com Ricky Onsman

      Great pick-up, Dave. “They” thank you.

  • Steve

    I tend to prefer the media query, combined with the JavaScript methods for reliability. The @font-face trick and use of SVG are great to save development effort and/or optimize bandwidth, but they don’t degrade well (or at all) for older browsers. Given that a discussion involving “retina displays” is generally highlighted for mobile development, I think that these considerations are still very important given the range of devices still in use (especially outside North America).