Responsive Web Design or RWD, has come a long way since it was first introduced in 2010, and you would think that by now, given the popularity of the subject, all things have been sorted out and all questions have been answered. Not quite. RWD is a moving target that continues to evolve, but for the most part the majority of the techniques used to accomplish the goal of an adaptable website are unquestionable except one, images.
There are many techniques out there that deal with images in some shape or form and some work better than others. From the simple “max-width:100%" css rule to javascript solutions, but after 4 years, working with images has gotten more complex than ever. In the Drupal world, for example, many suggestions, modules and techniques have come and gone. Many still remain. Some of the most popular techniques include Borealis, AIS (Adaptive Images System) and others. There is no clear winner at this point and this creates confusion and frustration for those just getting started with RWD.
The good news (sort of)
For a few years now, one technique that has gotten a lot of traction is the <picture> element. The picture element and associated features, according to W3C, are W3C standard HTML features that allow web developers to deliver an appropriate image to every user depending on a variety of conditions like screen pixel density, viewport size, image format, and other factors. The <picture> element seems to be moving in a direction no other proposed responsive images technique has been able to. This is promising because we are ready for standards for handling images in RWD.
So what seems to be the problem? What makes images so special and complex to deal with in a responsive website? Well, images are non-smart static binary files that don’t offer any type of dynamic interaction with your website without hand-holding by the designer or developer. They’re heavy in weight by nature and require special attention to avoid performance and UX penalties.
With that said, when looking for a solution for handling images in our websites, there are three critical goals that should be considered:
- Environment specific images: The goal should be to be able to provide images designed specifically for the device being used versus trying to force images meant for desktops into tiny mobile device screens.
- Bandwidth considerations: As much as we love our mobile devices and enjoy the high speed connections mobile carriers offer, we know those connections are unreliable and unpredictable at best. This creates a problem if we are working with high-res images. Retina-friendly devices love high-res images but we can’t ignore users with low or unreliable connections. The ideal solution would be to serve low-res images to devices that can’t handle high-res ones.
- Art direction: As pointed out before, resizing a desktop image to fit in a small device is not the ideal solution and definitely does not provide art direction. Perhaps the solution should be to provide a entirely different image cropped in a way that highlights the main areas of the image.
So let’s see how one of the ways for handling images measures against our goals above:
img {
max-width: 100%;
height: auto;
}
This technique does one thing and it does it well. Your images are resized to fit the device being used. However, as pointed out before, even if your images looks great on a mobile device, you are still loading a large image on a device that may or may not be able to handle it. This could potentially affect performance and UX. This method, while very popular, only meets one of the goals above but clearly does not save bandwidth and definitely does not provide art direction.
Now let’s see what the proposed markup for <picture> is and whether our goals are met by using this method:
Let’s take a look at what all of this means and whether our goals are met:
- <picture>: This element has no unique attributes of its own. The <picture> element is simply used as a container for <source>
- <source>: The <source> element has been updated for image loading after only being used for loading audio and video and the following attributes have been added:
- srcset: This is a required attribute which accepts a single image file path (e.g. srcset=“image.png”), or a comma-delimited list of image file paths with pixel density descriptors (e.g. srcset=“image.png, image@2X.png 2x") where a 1x descriptor is the default when it is left out.
- media: This is an optional attribute which accepts any valid media query that you would normally write in a CSS @media selector (e.g. media=“(min-width: 40em)").
- type: Another optional attribute which accepts a supported MIME type (e.g. type="image/webp" or type="image/vnd.ms-photo").
- size: This is also an optional attribute which accepts a single width descriptor (e.g. sizes=“200vw”), or a single media query with width descriptor (e.g. sizes=“(min-width: 40em) 100vw”), or a comma-separated list of media queries with a width descriptor (e.g. sizes="(max-width: 30em) 100vw, (max-width: 70em) 70vw)") in which the last item in the list is used as the default.
- <img>: The <img> element has also been updated to be used within the <picture> element as a fallback in the event the browser does not support the <picture> element or if no source tags are matched. The <img> element within <picture> is required. If the <img> is not present no images will be displayed. The <img> element is added as the last child of <picture> since the browser will ignore any <source> declared after the <img> tag. In addition, the <img> tag is where you add alternate text using the “alt” attribute of the image element.
- <source>: The <source> element has been updated for image loading after only being used for loading audio and video and the following attributes have been added:
As the HTML page is rendered, the browser will use the hints passed in as attribute values to load the appropriate image resource. It is important to list the tags in the right order as the browser will use the first <source> element with a matching hint and ignore the following <source> tags.
Using the <picture> element allows us to achieve our goals of environment specific images, bandwidth consideration and art direction. Another advantage of the <picture> element is the fact that all this can be accomplished with only HTML. No CSS or Javascript is required (for browsers that support it).
Items to keep in mind:
- <picture> requires <img> as its last child. Without it nothing is displayed. The <img> element within <picture> offers two advantages: Accessibility due to alternate text, and fallback for old browsers, which just show the <img> element.
- Think of <picture>, sizes and srcset attributes as overriding the src of the <img>
- <img sizes="(max-width: 40em) 100vw …">: The first match for “media query” rules, so source order does make a difference.
Browser Support:
As the date of this post, caniuse.com reports that the <picture> element is currently only supported on FireFox 33+, Chrome 38+ and Opera 25+. However, the momentum the <picture> element is getting promises that the browser support will continue to get better and better.
Despite the poor browser support, there are workarounds or polyfills that allow you to take advantage of the <picture> element now. One very popular technique is using the Picturefill javascript library created by The Fillament Group, an agency deeply engaged with the Responsive Images Community Group.
On the Drupal end things look very promising as it is confirmed that <picture> is part of core in Drupal 8 and its popularity and demand has made it possible to be back ported into Drupal 7, which means you can use it now and in part 2 of this blog we will do exactly that.
What’s Next?
Now that we have a basic understanding of what the <picture> element is and how it can be implemented, Part 2 of this blog will be in the form of a screencast which will go into detail on how to setup and use the <picture> element in a Drupal 7 website. Be sure to check back for part 2 of this blog series.
Opinions of when and if you should use the <picture> element differ:
To give you an idea of how dynamic and fluid the topics of responsive images and the <picture> element are, as I wrote this post I ran into an article which discourages developers from using the <picture> element on ALL images in a website. The argument is that the <picture> element should only be used when attempting to achieve Art Direction. I think it is worth reading, take a look.
vm: Viewport-percentage lengths. They are relative to the size of the initial containing block. http://dev.w3.org/csswg/css-values/#viewport-relative-lengths
Additional Resources
Responsive Design: Mobile Menu Options | Mediacurrent Blog Post
Top Marketing Automation Modules | Mediacurrent Blog Post
Top Drupal 7 Modules: Winter 2014 Edition | Mediacurrent Blog Post