Serving Retina Ready Images

27 August 2012

Looking at photography on Retina-class displays is an amazing experience. To call it a game-changer might be trite, but its true. Ever since my first experiment with displaying double-resolution images, I’ve wanted a general solution on my site to serve up the highest appropriate resolution file for any particular photograph I display. I knew it’d be a bit of work to sort out, so I punted it for a while.

When my Retina MacBook Pro arrived and I saw more examples of high-resolution work and how they compared to standard-resolution, I knew it was time to get into gear. I dove in to the current state-of-the-art and started working on how to implement a solution for this on my site. After a fair bit of experimentation and a few missteps, I’m there.

Here’s an example:

On a Retina-class screen using Safari or Chrome, you should be looking at a double-resolution image as long as you’re viewing this post on my website and not in a feed or aggregator. On other screens or using other browsers, you are seeing a normal resolution image.

How is this done? The answer is Picturefill by Scott Jehl (with thanks to Jason Grigsby for the pointer). It’s a compact bit of JavaScript which supports a syntax that mimics the Picture Element Proposal. In a nutshell, it uses CSS media queries to sort out the most appropriate image to use out of a set.

All you need is the right media queries for your particular needs—and you need to get them into the right order. Picturefill doesn’t evaluate the queries against each other to see which one is most appropriate. Instead, the last entry in the set with a media query that is true in the current display environment wins. Obvious in retrospect when you look at the Picturefill code, but I lost a few hours in the middle of the night sorting that important detail out.

The Future

For now, this is working fairly well for me and I’m continuing to fine tune things—along with working through other bits of layout as I make my site more responsive to various browsers. But, one thing I’ve really noticed I don’t like about the Polyfill syntax is that using two different media queries to satisfy the Retina/non-Retina display case is annoyingly verbose. Thankfully, the latest versions of the Picture Element Proposal have noticed this.

The picture element isn’t the only proposal on the table, it seems. There’s also a srcset attribute proposal for the img tag as part of the WhatWG Embedded Content standard that’s considerably more terse.

I’m not sure what the relationship is between these two proposals or the groups behind them, but either way it goes, I hope that we start seeing official implementation of a markup standard for this shortly. Until then, however, thanks to Scott Jehl’s work, I’ve got a solution that works and I’m quite happy about that.

Notes & Comments

  1. There’s an image size limitation in WebKit on iOS5 that will hopefully be lifted in iOS6. For now, if you’re viewing on a Retina iPad, the landscape orientation may not be displayed correctly.
  2. If you’re a photographer and haven’t seen photographs on a Retina-class display, make it a priority to do so. While you might not need, or even want, a Retina MacBook Pro right now—and might not until Photoshop is Retina-aware—you need to know where the state-of-the-art of displaying photographs on the web is going and be prepared to meet up with it in the near future.
  3. I'm not pushing the image set markup into my feeds for two reasons. First, the Picturefill JavaScript wouldn’t go along for the ride. Second, even if there wasn’t that concern, I ship a URL to smaller and more constrained version of the images through feeds for other reasons.
  4. Jacob Gordan noticed on Twitter that dragging a window from a non-Retina to Retina display doesn’t load the double-resolution image. On a read of the Picturefill code, that’s not too suprising. Picturefill hooks into window resize events, but I’m not even sure there’s an event to hook into for changing screens. Interesting.
  5. Thijs van der Vossen tweeted a link to his reasonable way to use high resolution images post. For smaller images, such as user interface elements, I wouldn’t disagree with his recommendation to just use double resolution images and let the browser scale things, although I think you really do want to keep file sizes in mind for mobile clients. I don’t think his argument scales well to larger images, however, such as the 1800px image I’m using in this post. There’s no way I’d want to ship that to an iPhone, especially on a mobile connection.
  6. David Magda asked via email whether using the resolution media query would be more vendor neutral. It’s a good question and I don’t have an answer. So far in an effort to just get things working, I’ve just been following the examples of others and using the -webkit-min-device-pixel-ratio. David also reminded me that other browsers exist and I added a section to the post about the Mozilla and Opera variants of min-device-pixel-ratio.
  7. The W3C Responsive Images Community Group has posted their first draft of the Responsive Images Extension, aka the picture element.