The popularity of responsive web design is constantly exposing behaviors that web browsers have gotten away with over the years. Many of these behaviors — while brilliant for a single-screen web — become a direct hindrance when dealing with the multi-screen extravaganza that we face now.
One of the most hotly debated topics is responsive images. This was a topic widely exposed by Filament Group due to their work on the Boston Globe, and it continues to be an issue for every bandwidth-conscious site today.
The foundations of this topic have been hotly debated and oft explored in the past year, so here’s a list of articles that capture the history of responsive images and demonstrate the challenges developers face on a modern site:
- Mat Marquis, part of Filament Group and the Boston Globe team, took it upon himself to take the helm of this issue, writing about the initial challenges and creating the Responsive Images Community Group. The group has proposed a solution and is busy solidifying a web standard for responsive images, backed by the trial and error of developers worldwide.
- Jason Grigsby has written extensively about responsive image techniques, deftly balancing the need for simplicity on the authors’ side, while recognizing the underlying tech issues browsers inadvertently (and rightfully) created during our beloved single-screen golden era.
- Robert Paul Lloyd writes about how no solution is ideal, suggesting that we go back to the drawing board and create an entirely new image format. In the long term this is pretty likely. For certain types of imagery a bandwidth-cheap, scalable format already exists in SVG, icon fonts, and other vector formats. A similar vessel needs to exist for photos too.
Whatever the final outcome of the standards process, if you find yourself needing responsive images today there are several approaches, the most successful of which is currently the
In a nutshell,
Picturefill is its own open-source library, available on Github.
Implementing responsive images on a Drupal site
The latest responsive site that Four Kitchens launched, Full Plate Living, tightly integrates responsive images with Drupal content. The methods for doing so are thankfully rather easy, but as with all things Drupal there is a bit of a learning curve to get started. Responsive images can be added to content, views, etc. with the help of two contributed modules: Breakpoints and Picture. These two modules rely on Drupal’s core Image Styles module to output images in various sizes using a URL-specific, render-on-demand system.
In responsive web design breakpoints are used with media queries to determine when new CSS rules should apply to the site’s markup. As its name suggests, the Breakpoints module allows your site to define media queries on which you’d like to take action. The module provides a canonical list of breakpoints that are accessible from the database and thus surfaced to your site’s code. The Breakpoints module also has the notion of a “breakpoints group.” Groups are particularly useful for defining sets of breakpoints that are only relevant to certain parts of the site. These breakpoints can then be semantically referenced by their group name which allows you to reuse breakpoint names between groups, even if the media queries aren’t the same.
In the case of Full Plate Living we had one global set of breakpoints that was defined in the theme’s .info file:
breakpoints[smartphone] = (min-width: 320px)
breakpoints[fourhundred] = (min-width: 415px)
breakpoints[smartphone_only] = (min-width: 320px) and (max-width: 767px)
breakpoints[smartphone_landscape] = (min-width: 480px)
breakpoints[smartphone_landscape_only] = (min-width: 480px) and (max-width: 767px)
breakpoints[small_menu] = (min-width: 430px)
breakpoints[smaller_menu] = (min-width: 421px)
breakpoints[recipes_landing] = (min-wdith: 520px)
breakpoints[user_reg] = (min-width: 625px)
breakpoints[tablet] = (min-width: 768px)
breakpoints[tablet_only] = (min-width: 768px) and (max-width: 979px)
breakpoints[desktop] = (min-width: 980px)
Additional breakpoint groups were added for content types so that the amount of markup required for responsive images could be kept down (one breakpoint means two picture options: the default, and the one defined for the breakpoint).
Configuring image styles
Core’s Image Styles are used to format the images that will be used in the picture element. It’s a good idea to give the image styles meaningful names so that configuring the Picture module is more straightforward. In the case of Full Plate Living we generally used two image styles per page: STYLE__full for images delivered to large viewports, and STYLE__mobile for images delivered to small viewports.
Finally, when you’re defining the display style for your image fields you will choose “Picture” as the formatter for the image. The settings for this field will allow you to choose the “picture group” and a “fallback” image style. The fallback image style will be used if no breakpoint conditions are met. If you’re building mobile-first, this would be your base mobile style definition and should be the smallest image that will be delivered to the client.
Show me the data
To demonstrate the advantages of the
<picture> element we captured data from the Full Plate Living recipe landing page. See those beautiful, gigantic images below the search? Such a huge image is not needed for the same effect on a small screen. Implementing
<picture> resulted in a difference of 157K out of a max page weight of 746K. Here are the two network waterfalls:
The three images in this screenshot that start with 2012 are the mobile-formatted images. They total approximately 40K at the default breakpoint.
Looking again at those images with the same 2012 prefix, we see a total of 197K, meaning we are preventing the site from serving mobile users with approximately 157K of data that they don’t need.
You can see that the download “initiator” for the images is a script — not the HTML page — due to the picturefill script modifying the DOM and specifying the image that should be used. This DOM modification causes the markup on the page to differ based on the viewport, visible in this gist.
Div + data-attributes
<picture> element was used on Full Plate Living, but for now it’s considered slightly more future-proof to use
<div> elements with data attributes.
<div data-picture data-alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
<div data-src="medium.jpg" data-media="(min-width: 400px)"></div>
<div data-src="large.jpg" data-media="(min-width: 800px)"></div>
<div data-src="extralarge.jpg" data-media="(min-width: 1000px)"></div>
<!-- Fallback content for non-JS browsers. Same img src as the initial, unqualified source element. -->
<img src="external/imgs/small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
The picturefill script and Picture module both currently use the
<div> method, so although your markup will look different, the end result will be the same.
We all recognize the need for a responsive image container on the web. Today’s solution might look very different from tomorrow’s, but the need for device-optimized media will continue to grow as fast as the variety of devices accessing the web. Just hang on, remember to test, and enjoy the ride!
Credits: this article was co-written by Elliott Foster.