Looking for a way to create responsive images using only
HTML? No fear! The < picture > element is coming! The good people over at the Responsive Images Community Group
of W3C have been working hard to champion the adoption of the < picture > element. If you're into geeky web history, I'd check out this article
about the process; it's pretty interesting. At one point there was even an Indiegogo campaign that raised over $15,000 to help get the element implemented!
In this article, I will go over some of the current fixes to the responsive images problem, how to use the < picture > element, and the current level of support for < picture > in major browsers.
Currently there are a few (flawed) fixes for the responsive images problem. I'll quickly go over a few of the most popular solutions and discuss some of the issues the current solutions present.
1. max-width: 100%;
A favorite fix for responsive images is to set the max-width of an image to 100%. This way, images will always be the size of the container. If the container is set to a percentage width, it will scale responsively with the container. Most current web browsers support this fix, and make sure that the aspect ratio of the image is maintained.
This problem with this fix is that if you are designing for all size screens, you will need to start with a pretty large image file to account for large screens. Even though on smaller screens the browser will only render a percentage of the large image, the full large image is still loaded. This negatively impacts load time and user experience.
Check out this graph from HTTP Archive:
That big ol' chunk of pie? Images. With some crafty implementation of the < picture > element, you only load the image size suitable for the screen size/orientation. Yay! Less load time, more happy users.
2. But Emily... what about media queries?
I knew you were going to ask that... Media queries for responsive images rely on the use of background-images, which are not semantic. Making your site semantic allows your site to integrate better with different user agents, make maintenance of code simpler and more efficient, be easier for search engines to read, and overall send a signal that your site is up to date with the latest web standards. All good things. Plus think about it, what does HTML stand for? Hyper Text Markup
Language, it is used to markup what's on the web. Assigning meaningless markup to content defeats the purpose of HTML in the first place. I think Mike Robinson from HTML5 Doctor
said it perfectly:
I’m not marking this up for me, but for everyone who can benefit from the enhanced meaning. Whether it’s the browser, a search engine spider, an accessibility tool, the person you pass the project on to, or even future you returning to the project in six months time, the markup indicates how the content should be interpreted. - Mike Robinson
Okay, rant over.
Not to mention, background images are not accessible! If your user is using a screen reader or images are not loading for some reason, all information contained in the image is lost.
3. Server-side & 3rd party solutions
There are also a few server-side and 3rd party solutions out there but they often require too much time-investment, cost too much, or don't allow for art direction. I haven't found one that satisfies all my requirements yet.
If you'd like a more in-depth list of all the different types of responsive image solutions, check out this list that Chris Coyier and Christopher Smith created here
. It's a bit outdated but it gives a matrix-style overview of all the techniques available.
Using the < picture > element is pretty straight-forward. Here's the syntax:
One < picture > element, followed by as many < source > elements as you'd like, and finally a < img > element as a fallback, then, of course, don't forget to close your < picture > element. Set as many attributes as you'd like in < source > depending on what type of responsive image issues you are facing.
< picture >
< source />
< source />
< source />
< img />
< / picture>
Though note that by using < img > as the fallback the < img > will be loaded before the < source >, since rendering engines scan the page for images to load first. Two images are loaded in this case. This increases processing time, something we were trying to avoid in the first place.
A fix to this is to use < object > and an invisibly-styled < span > for the alt-text (making it accessible). This is a little annoying as it requires two lines of code and some CSS to hide the span, but I believe it is preferable to loading two images. The < object > is still semantically correct as < object > elements "can represent an external resource, which, depending on the type of the resource, will either be treated as an image
, as a nested browsing context, or as an external resource to be processed by a plugin." according to the HTML5 W3C Reccommendation
. Though, it's not the MOST semantic element that can be used, which is irksome.
There is hope though; Robin Berjon and Yoav Weiss are working on browser implementation solutions that would not load the < img > before checking out the < source > element. This would solve both the duplicate-loading issue and the semantic issue. Until then, some hacking is required.
Here's an example of a markup in practice using the < object > fix:
<source src="small.jpg" type="image/jpg" media="screen and (min-width:320px) and (max-width: 480px)"/>
<source src="medium-ipad.jpg" type="image/jpg" media="screen and (min-width: 768px) and (max-width: 1024px) and (orientation: landscape)"/>
<source src="large.jpg" type="image/jpg" media="screen and (min-width: 1224px)/>
<source src="xl.jpg" type="image/jpg" media="screen and (min-width: 1824px) />
<object data="other.jpg" type="image/jpg"></object>
<span class="fallback-alt">Image Alt</span>
This is just one example of how to use the < picture > element. Since it essentially acts as a container for < source > the magic happens when you utilize attributes of the < source > element creatively to solve your responsive needs. < source > attributes are as follows: srcset
, and type
. If you get lost, I always find it helpful to check the documentation for the < picture > and/or < source > element at either HTML Standard
or the W3C
Currently, Chrome 38 and Opera 25 support the element, while Firefox is expected to adopt it in the near future, and IE will... get to it eventually... (it's on the IE Roadmap)
@joshuamauldin @tobint We don't know when they will ship yet. We haven't started development. Follow status at http://t.co/lCeUmeaKzN.— IE Dev Chat (@IEDevChat) October 2, 2014
If supported by all major browsers AND implemented so that the < img > element is not pre-loaded, this could be the magical fix to all your responsive image issues. The web is not quite there yet, but it's still good to know how the < picture > element works, and the benefits of its use over other responsive image techniques.