Responsive Images And The Perfect Polyfill — Smashing Magazine


Not since the early days of web standards have I seen our community rally around a seemingly small issue: responsive images.

Over the last four years (yeah, it’s been about four years), we’ve seen many permutations of images in responsive design. From the lazier days of setting max-width: 100% (the absolute minimum you should be doing) to more full-featured JavaScript implementations, such as Picturefill and Zurb’s data-interchange method, we’ve spent a lot of time spinning our wheels, banging our heads and screaming at the wall. I’m happy to say that our tireless journey is coming to a close. The W3C and browser makers got the hint.

The State Of Responsive Images

In our search for the holy grail of serving the right image to the user, our attitude towards browser makers until now has largely been, “Forget you — we’ll do it ourselves.” I’m certainly no exception. We were so attentive to responsive images and were exposed to all of the guesswork and trials that are not typically released to the public that we got impatient (rightfully so) and did it with JavaScript.

The difference between a CSS transition and a responsive image is, of course, how they degrade. If a CSS transition doesn’t work, who really cares? Your interface might be a little jumpy, but the experience as a whole won’t really suffer because your users will still be able to accomplish their goal and consume the content they need.

That really isn’t the case with images. How does a new image tag degrade? The img tag is so widely accepted that I couldn’t even find when the W3C recommended it as a standard, other than a small reference in the HTML 4.01 specification. Replacing or even expanding on the img tag would be like telling Frank Sinatra to wear a baseball cap instead of a fedora — you’ll get some pushback.

Resource Problems

As responsive design grew in popularity and as the media through which users consume information became uncontrollable, we slowly realized that img by itself wasn’t going to cut the mustard. We started asking questions like, “What screen size is the user on?” and “What’s the pixel density of the screen?” These questions fuelled our image techniques until we realized that screen size and pixel density have absolutely no relationship to the amount of bandwidth available to serve up a huge high-definition image.

The RICG began working on the picture element, sharing its work with the W3C along the way.
The RICG began working on the picture element, sharing its work with the W3C along the way.

The solutions got pretty complex. Talk of the picture element started, and a group called the Responsive Images Community Group (RICG) appeared. The RICG began working on the picture element, sharing its work with the W3C along the way. The result has led us to today and this discussion about all of the progress that’s been made.

The Introduction Of srcset

Because most of the responsive-image community was on board with the picture element and looking forward to it because of the great polyfills, such as Picturefill, it went ahead and released a well thought-out and fleshed-out document outlining something called srcset, which is an extension of the standard img tag. Yeah, I know — it feels like it came out of nowhere. It was also super-complicated and overly limiting by restricting you to (implied) pixel values and using a microsyntax that didn’t allow for scalability with media queries in the future. Luckily, the syntax has matured into what we have today, which is a fairly robust recommendation.

Most recently, Andrew Clark said it best when he tweeted, “Looked at the responsive images srcset & sizes attributes for the first time. Blimey it’s complicated.”

I couldn’t have said it better myself. Let’s look at what we’re dealing with:

dog  

Three major attributes are in the snippet above: alt, src and srcset. The alt attribute is the same as it’s always been; src is the fallback if srcset isn’t supported; and srcset is obviously the meat and potatoes here.

We can see three arguments in srcset. The first is the image path. The second gives the browser information about the natural widths of the sources, so that it knows which resource to serve to the user (based on the user’s preferences and cross-referencing with the sizes attribute – I told you it was complicated). The last piece sets the optional pixel ratio (2x in this example specifies the high-definition image).

One thing I really love about srcset is that the specification states that the browser should contain image-allocation preferences for certain bandwidth situations. This means you don’t have to worry about serving a 2x image to a high-definition screen if that device is on a cruddy 3G connection. The user’s preferences should take over, and the browser would choose the appropriate image to serve.

Preparing For The picture Element

After much complaining about our new weird friend, srcset, the RICG continued working on the picture element, which is finally getting some serious traction with browser makers… well, that is, with Chrome. The proposed syntax for the picture element might look familiar because we saw it largely in the first version of Picturefill, and it’s not unlike how and are marked up.


  
  A fat dog
  

As you can see, a source tag is in the picture element, along with a normal img tag. Just as we saw with src in srcset, the img is a fallback. In the source tag, we have what looks like a media query, alongside a srcset attribute that contains the same image-source and pixel-density arguments as before. This seems like a nice clean way to popularize responsive images; we’re generally familiar with the syntax, so it should be easily adopted.

Browser Support

The srcset attribute has been supported in Chrome since version 34. At the time of writing, it is not supported anywhere else. Mozilla appears to be working on an implementation (fingers crossed). Internet Explorer is nowhere in sight.

The picture element has even worse support; it isn’t even in Chrome yet. But like Mozilla with srcset, Google is currently working on implementing it. If you can stomach reading through a specification, I highly recommend it. Even though there isn’t much of a plot and the character development is pretty weak, it’s still a pretty good read.

Picturefill 2.0 was created because native support is reasonably close. You know we’ll need a rock-solid polyfill to use when the time officially comes, so let’s take a look at it!

Introducing Picturefill 2.0

Picturefill 2.0 was recently released as beta, and it’s quite a large jump from version 1. The RICG really aimed to create a one-stop solution for responsive images. The challenge was to create a script that allows you, the developer, to use any combination of the solutions currently being standardized, without bloating it to the point that not using it at all would be more lightweight.

Imagine polyfilling an image that would normally take 2 seconds to load using a JavaScript file that takes 10 seconds to load — it wouldn’t make much sense. Picturefill 2.0 avoids this by following the specification very closely (with some intentional omissions, which we’ll go over in a bit) and letting you use either srcset or picture or a combination of the two.

Picturefill is an responsive image approach that mimics the proposed picture element using divs.
Picturefill is an responsive image approach that mimics the proposed picture element using divs. (Larger version)

While we can’t reliably achieve everything in the specification using JavaScript (such as reasonably detecting bandwidth, which would be a user setting anyway), we can certainly take care of all of the pieces that are meant to be in HTML (i.e. elements and attributes). This version of Picturefill gets us one step closer to not needing Picturefill, which is the ultimate goal of anyone who has ever written a polyfill.

If you’re currently using version 1.0, I highly recommend upgrading to 2.0. It’s a big step towards a better solution to serving the correct image to the user. Some big changes have been made to the syntax and functionality. Let’s look at what’s new.

What’s New In 2.0

One thing that makes this polyfill different from others that I’ve seen is that it polyfills a concept, not just an unsupported block of HTML. Picturefill 1.0 used spans and custom attributes to mimic how we thought responsive images should work. For the record, it is a great solution, and I currently use it for many of my projects that haven’t been converted to 2.0.

In the last year or so, the specification for srcset and picture have matured so much, so we can now actually get to use something close to the real syntax. Picturefill is starting to look like a true polyfill, one we can strip away when real support shows up.

Installing And Using The Polyfill

If you’ve read this far, then you’ve probably dealt with some form of polyfill in the past. This one isn’t much different. Polyfills are supposed to be set-it-and-forget-it (to steal a line from Ronco), but because this is an HTML polyfill, you’ll need either to create the picture element manually or use some form of HTML shiv to do it for you. Luckily, HTML shivs are pretty common and ship with toolkits such as Modernizr; just verify that picture is supported in whatever shiv you choose.







Scroll to Top