Jump to main navigation, main content

Archived entry | Matt Wilcox .net

Supplying high definition content and design to Retina devices like the iPhone 4

The iPhone and other Retina displays require us to send high definition images to match the quality of native applications, or else our webpages will look low resolution and pixilated. Here’s how to send HD images for CSS and HTML.

(You can see the results on an iPhone4 by viewing the test page)

Sending high-def images via CSS

Is well documented and fairly simple to achieve using media queries:

  /* iPhone with Retina display */
    @media only screen and (-webkit-min-device-pixel-ratio: 2) {
      .hd {
      background-image : url(600x600.jpg);
      background-size: 300px 300px; }
    }

This media block is picked up only by the iPhone 4, and we specify a rule to load a double-sized picture to use as a CSS background, and then we size the background back to normal (i.e., the box-model dimensions) using background-size. Learn more about media queries from Apple’s official documentation.

I don’t know why Apple decided to use a propriety CSS switch instead of the W3C resolution Media Query, but there we go, this is what works for now.

Sending high-def content images

Essentially the same technique works for standard <img/> tags, so we can provide high-def content images as well as high-def CSS images (imagine Flickr doing this). Embed a double-size image and specify image dimensions of half:

<img src="800x800.jpg" alt="" width="400" height="400" />

Problems and caveats

This technique is something I’d class as a hack rather than a real solution for a few reasons.

  1. It requires that you know the size of the image you’re embedding - which you may or may not.
  2. There’s the major downside of having supplied a far higher resolution (and far larger filesize) than most devices will need.

The work-around for both is to do our iPhone high-def enhancements via JavaScript instead of baked into the HTML (I’ll show you how next).

Keep in mind that iPhones can be on slow mobile networks and data can cost a lot! It’s also worth remembering that additional HTTP requests are what slow mobile more than file-size, so embedded @media declarations in your CSS file (as above) might be faster than using them in a <link /> tag. Which is best for you will depend on your project.

Using jQuery to mitigate the bandwidth issue

There are a number of ways of going about this, depending on your use-case, but considering most websites will not have high-def content for all images I’d suggest building the site as normal, adding a class of “hd” to any images you want replaced with high-def versions, and then running a jQuery function against them to match a given naming convention. e.g., append “-hd” to the image filename on the high definition version of that image.

So, all you need is a version of the image that’s twice the width and height of the standard image, named exactly the same except for adding “-hd” on the end of the filename, and a class of “hd” on the image to be replaced.

Example jQuery to automate HD embedded images

$(document).ready(function(){
  /* Only apply if we're on an HD iPhone/iPod */
  if(window.devicePixelRatio >= 2) {

    $("img.hd").each(function() {
      // get the image src and dimensions
      var old_src    = this.src;
      var box_width  = this.width;

      // append "-hd" to the image filename
      this.src = old_src.substr(0,old_src.lastIndexOf(".")) + "-hd" + old_src.substr(old_src.lastIndexOf("."));

      // wait for the hd image to load so we can reliably get its dimensions
      $(this).load(function(){
        // make sure the image is sized correctly, even if there isn't a html attribute
        if(this.width != box_width) {
          var hd_width = $(this).width();
          var new_width = hd_width/2;
          $(this).width(new_width);
        }
      });

    });
  }
});

view the test page on an iPhone 4

Comments

skip to comment form
  1. Juan Ignacio Serra posted 8 days, 23hrs, 24mins after the entry and said:

    Nice solution! But, what happens with iPhone/iPods with no retina display? They still get the HD version even if it's not needed?

  2. Matt Wilcox posted 9 days, 0hrs, 24mins after the entry and said:

    Good catch! I'd forgotten to add the pixel ratio check into the javascript. And after thinking about it some more, realised I don’t need to sniff for the iPod/iPad as we’re only after HD devices, so we only need check the device pixel ratio. Thanks.

From the archives

Other enteries filed under:

Web Development

Site information

Built with valid XHTML and CSS, designed with web standards and accessibility in mind. Best viewed in a modern browser [Firefox, Safari, Opera]

This domain and all content is a copy of my old website, for historical purposes only.