High-res images for retina displays

The release of the new iPad makes high-resolution alternatives for images on retina displays more important.

As early adopting web-workers, our challenge is to remember more is a relative term. Addressing the classic challenges still affects more users than hi-resolution images. Typography; quality, site specific, imagery; and mobile sites are of greater importance that our fancy new toys.

For this post, I’m exclusively addressing hi-resolution images for retina devices. It comes from the same school as classic responsive images focused on the screen’s size.

Some very smart people have suggested numerous techniques for responsive images. Jeremy Keith has a nice round up. The techniques I’m using below are for solving a very particular problem.

The two situations to consider are CSS backgrounds and inline images.

Background images

The min-device-pixel-ratio media query will cover this. Media queries have been written about more than once, so I’ll just give you the code.

.background {
  background: url(img-x1.jpg) no-repeat 0 0; 
  width: 600px;
  height: 400px; 
} 
@media only screen and (-webkit-min-device-pixel-ratio: 2), 
  only screen and (-moz-min-device-pixel-ratio: 2), 
  only screen and (min-device-pixel-ratio: 2) { 
    .background { 
      background-image: url(img-x2.jpg); 
      background-size:600px 400px; 
    } 
}

A working example is on the demo page.

Inline images

My aim with the img tag is to

  • only load one image,
  • use feature sniffing, and,
  • have a suitable – non JavaScript – fallback in place.

Document.write

The easiest solution was to write a JavaScript function that detects the pixel ratio, place it in the HTML header, use document.write and die inside.

The function is passed the low-resolution file name, the high-resolution file name & pixel ratio at which to display the hi-resolution image (defaulting to two).

The inline code to display the image is:

<noscript>
  <img src='img5007-lores.jpg' width=600 height=400 /> 
</noscript>
<script> 
  document.write("<img src="" + 
    fdp_retina(' img-x1.jpg', ‘img-x2.jpg’, 2) + 
    "" class="retina retina-js" width=600 height=400 />"); 
</script>

View the source of our demo page to see the function code.

Placeholder code

The second option is to use a placeholder with data-* attributes to be replaced JavaScript. Images are inline elements so an inline span is used.

<span class="retina-holding" data-width="600" data-height="400" 
data-lowres="img-x1.jpg" data-hires="img-x2.jpg" data-hireszoom="2"></span> 
<noscript> 
  <img src='img-x1.jpg' width=600 height=400 /> 
</noscript>

The easiest way to select the placeholder spans would be to use jQuery and the selector span.retina-holding, we could then use jQuery’s data function to get the attribute values. Call me old fashioned, but I think 32KB – 92KB without gzipping – is a little excessive for two small functions.

Instead I used a getElementsByClassName pollyfill, selected the required elements and rolled my own code to get the data-* attributes with a fallback for older browsers. If jQuery – or another library – is already included in the page, it makes sense to use it.

The downside to this method is the page renders, the placeholders are replaced and the page renders again. This is not ideal.

Again, you can see the function code by viewing the source of our demo page.

Inline images server side

On the first page load, I’m inclined to go with the placeholder method and use JavaScript to set a cookie with the appropriate resolution.

On subsequent page loads, I would read the cookie server side and replace the placeholder and noscript palaver with a simple image tag.

This avoids race conditions on the first load, and re-rendering on subsequent page loads.

The primary consideration when deciding whether to add hi-resolution images for retina devices is statistics. If virtually no one is going to receive any benefit, it’s a waste of your time.

As always, there is a healthy mix of nuance in the decision. Are there PR or Keeping The CEO Happy advantages? Even with a low number of visitors, it could become worth your time.

We’re working on a WordPress plugin to allow us to add retina images to this site; the PR benefits are worth our time. We’ll be releasing the plugin publically, keep an eye on the blog.

Leave a Reply

Your email address will not be published. Required fields are marked *