HTML5 <picture> Element

by Christopher Schmitt

Responsive design techniques are a way for developers to adapt a site layout to a wide range of devices, from desktops to iPhones, and have it consistently look sharp and load quickly. And no responsive design solution is complete without an adequate technique for dealing with images.

An ideal adaptive image strategy should do the following:

  1. Fit the screen. Most images within desktop layouts are too large to fit within the tiny screen real estate of a mobile device. An adaptive strategy needs to resize the image, via CSS or otherwise, so that it can resize into a mobile screen.
  2. Reserve bandwidth. High-res images are enjoying greater popularity with the advent of retina displays and loading high-resolution images can eat up quite a bit of bandwidth. While this may not make a lot of difference when browsing on your desktop over a fast wi-fi network, it can make for an achingly slow site when surfing over a 3G network on a mobile phone. So, if you can serve up a lower-resolution image when you are viewing your site on a mobile device, browsing speeds up considerably.
  3. Take art direction. Not all images look good when squeezed onto a small display, particularly images with a lot of detail. When displaying a site on a mobile device, you might want to serve up an entirely different image altogether – perhaps the original image cropped to highlight a central object.

Current Responsive Image Solutions

The simplest technique for adapting images to small screens is to include the following CSS rule in your media query:

img {
    max-width: 100%;
    height: auto;
    }

This rather elegant solution effectively squeezes all images that are too wide for your mobile screen within the containing element.

While this technique effectively satisfies the first criteria of an ideal solution as it does manage to fit all images within smaller screens, it fails our last two criteria. First, it doesn’t save on bandwidth, as it’s still loading the original high-resolution images, even if they’re squeezed within a smaller layout. And, it certainly doesn’t take into account art direction, as this technique doesn’t load alternative images within different contexts.

Javascript solutions are popular, such as HiSRC (a technique I put together, which you can find here). This particular solution, which depends on jQuery, checks to see how fast the user’s bandwidth connection is: if a faster bandwidth is detected, then a higher-resolution image is delivered (based on a specialized markup specifying images url’s of varying resolutions) This solution is complete as it adapts to bandwidth restrictions and respects art direction, since we can specify different images.

Note: A similar solution to HiSRC is Adam Bradley’s Foresight.js.

There are sever-side solutions, like Adaptive Images by Matt Wilcox, which make use of an .htaccess file and PHP script to automatically resize your images based on the user’s screen size. This solution is great for folks that don’t want to add extra markup to their image tags, but it doesn’t allow you to serve up different images to different types of devices (i.e., doesn’t satisfy the “art direction” criteria).

Finally, there are third-party solutions, such as ReSRC.it. They try to make responsive images painless by doing all of the work for you: they host the images on their servers, and deliver bandwidth-friendly images to mobile devices on the fly. While great for those who want a hands-off approach, these services can cost money, and you are out of luck if the company goes out of business.

While these solutions meet some, if not all, of the criteria for a successful responsive image strategy, they rely on external scripts or services (which can always fail to load or cease to provide), and add an extra level of complexity to your site. It would be great if there was a solution built-in to HTML itself that would meet all of our needs.

The <picture> Element

Enter the <picture> element. Proposed to be a part of HTML5, the <picture> element is a solution that is both complete and in need of no additional scripts or third-party services to do the job.

The syntax is as follows:

<picture>
   <source media="(min-width: 64em)" src="high-res.jpg">
   <source media="(min-width: 37.5em)" src="med-res.jpg">
   <source src="low-res.jpg">
   <img src="fallback.jpg" alt="This picture loads on non-supporting browsers.">
   <p>Accessible text.
</picture>

Within the <source> tags, we can specify the width of the device to restrict the image to using the media attribute. The first line specifies a high-resolution image to be loaded onto desktops, while the next two lines specify lower-resolution images for tablets and phones, respectively. The <img> element serves as a fallback for browsers that do not yet support the <picture> element, while the last line specifies text to be displayed when all else fails (similar to the <image>alt attribute).

This technique (while syntactically verbose) does potentially satisfy all of our criteria for a complete responsive image solution.

Are there any problems with this solution? Other than the fact that it isn’t yet supported by modern browsers (which is, granted, a big hurdle to overcome), there is a problem with the syntax in this example: Browsers routinely “look ahead” and pre-load all images within <image> tags prior to loading the rest of the document. So, the fallback image is always loaded, regardless of whether the other images are loaded or not. This doesn’t exactly bode well for our bandwidth criteria that two images are always loaded into our mobile devices for each picture element within the document.

David Newton notes that we could use the <object> or <embed> element instead of <image> to contain the fallback image, as browsers don’t pre-load images within these tags. His complete solution is outlined in this article.

Once details of this element are hammered out, the <picture> tag could be the solution for adaptive images.

Worth noting that other solutions, such as the srcset attribute, are also being discussed and are starting to see support. The srcset attribute was recently implemented in Webkit.

If you can’t wait for modern browsers to support the <picture> element, you can check out Scott Jehl’s Picturefill script, which mimics both the syntax and function of the <picture> element (using the <span> element, instead).