Responsive Images: The Ultimate Guide
Chances are that any Web designers using our Ghostlab browser testing app, which allows seamless testing across all devices simultaneously, will have worked with responsive design in some shape or form. And as today's websites and devices become ever more varied, a plethora of responsive images techniques are appearing to serve developers' needs.
However, responsive design can seem like a minefield. The sheer range of responsive image options on the Web is daunting - and that's before you get into facing the obstacles specific to the site you're working on. But have no fear! Below is a basic outline of what responsive images are, how they can affect your work process, and some of the key defining factors that we think should apply to any designer's thinking, whichever route you choose...
What Are Responsive Images?
Put simply, responsive design is an approach that enables your website to fluidly adjust within the parameters of any device - involving a minimum of scrolling or zooming. In other words, creating great-looking sites which are dynamic and flexible enough to be visually responsive to any screen, from mobile widths right up to desktop format. And to make that possible, you of course need a flexible approach to images. Simple, right?
Well ... yes and no. While responsive images are now widely used and fairly easy to use in basic layouts, anyone designing more complicated sites will know that issues can quickly rear their ugly heads. Needless to say there is no one key to fit all locks - so we've listed seven of the most common problems below, along with a basic run-through of effective techniques related to each problem, to help you get your site running smoothly.
What Are The Problems?
One major factor in the need for responsive images is overall website size - even today, a huge percentage of mobile-version sites are as large (or even larger) than their desktop versions, thereby affecting performance negatively. Images play a large part in this, as image quality and size in general continues to increase, but it makes little sense if the data is wasted by mobile devices or desktops with low bandwidth connection. So to improve efficiency, more designers now using responsive images - however, these often open up their own cans of worms.
Problem 1 - Semantics
Making responsive images work cleanly and reliably across multiple platforms sometimes involves using techniques that aren't ‘semantic'. Why? Because when the src of an image points to a real image, with an alt text to describe it, even if the src is the smallest image possible, it means you're downloading unnecessary data.
To get around this, some of the techniques described below require the src of the image to be removed, or to link to a transparent GIF for example. If this doesn't suit and you're looking for a semantic approach, then Adaptive Images by Matt Wilcox, or the HiSRC jQuery plugin by Marc Grabanski and Christopher Schmitt, are two excellent options to look at.
If the site you are working on has a large amount of legacy images, it may not be workable to go through and adjust every image with special markup or specialised CSS. In this case, Adaptive Images is arguably the best solution out there. It requires no custom markup for any images and thus enables backwards compatibility by resizing images automatically. However, it does require the Apache 2 Web server and PHP 5.x, which may not be compatible with your site's platform (more on this later). It also requires that your images be hosted with your Web server, as opposed to elsewhere via a delivery network.
Unlike Adaptive Images, HiSRC does require custom markup in the HTML, and so may not be appropriate in the case of sites with high legacy content. On the other hand, it gives you the freedom to specify custom cropping or zooming of images for smaller platforms (the ‘art-direction problem' discussed below), as well as enabling the script to pick different image resolutions according to network speed (‘the bandwidth problem') - neither of which Adaptive Images does. On the downside, HiSRC will only work if you're using the jQuery library, so if that's not an option try one of these other solutions.
Problem 2 - Art Direction
A picture tells a thousand words ... most of the time. Many responsive image techniques enable you to provide several resolution versions of an image, which can then be used accordingly for suit a given platform. However, this can sometimes have a negative effect where the message of the image is diluted or lost altogether. What's the minimum size for an image? The answer, of course, depends on context.
Even the most stunning images can lose their power when scaled down to fit the confines of smaller devices such as mobiles. If this predicament applies to your site, you'll need a solution that addresses the ‘art-direction problem' by enabling custom cropping and zooming specifications. Both the HiSRC and Picturefill techniques (described below) offer lots of flexibility here, but remember - if your site has a high number of legacy images, you'll be doing a lot of custom markup, which perhaps isn't desirable.
Problem 3 - Validity
If you are customising markup, checking markup validity using a validation service such as W3C ensures that a construct follows the correct syntax of whatever language it works with (for example, HTML). While most of the time browsers are able to think ahead to present Web pages that aren't strictly ‘valid' without any problems, these results can sometimes vary between one browser and another. In rare cases, it can cause confused layouts or even crashes. ‘Validating' every page is a bulletproof way of identifying these problems before they occur.
<picture> element to display responsive images, and it works excellently in spite of being technically invalid syntax. Go ahead with whatever works best for you: if validity is a must, then Adaptive Images or HiSRC may be a better fit.
Problem 4 - Bandwidth Capabilities
Much as we'd all like to say otherwise, a world of super-speed connections and lighting-fast load times for everyone is still some way off. That's why in many developers' opinions, responsive images ought to consider the bandwidth available on any given device, and adjust the image size accordingly to cut out excess downloads.
Foresight.js by Adam Bradley is a solution that works as a kind of connection speed checker, by first downloading a 50K test file and then determining which size image suits best: a technique that is also available with HiSRC. The downside of this? The test image means an additional 50K download, and a potentially delayed page load time. However, many consider this preferable to serving up large images that go unused.
Problem 5 - Server Side Components
Problem 7 - Third Parties
If you prefer to outsource, Sencha.io Src is a completely third-party technique for resizing images to fit any given user. By acting as a proxy for images, it ensures you need never delve into custom configurations on your server - just point the image to Sencha.io, which then uses its user-agent string to detect the parameters of the device, and your image is resized!
There are several other options if you're taking the third-party route. An alternative to Sencha.io is ReSRT.it, which offers a very similar service but without user-agent detection or cookies. It also allows for bandwidth detection and flexibility to address the art-direction problem, if that applies to your site. Device Atlas Cloud, Responsive.io, and Thumber.io are other options, just to name a few.
Needless to say, third-party dependency is to be treated with caution. While these solutions often work perfectly and are convenient (and free for individual users, in the case of Sencha.io) you always run the risk of unexpected downtime. So it's best to weigh up the potential consequences before you jump in!
Best Practice Today
Picturefill 2.0 was recently released as beta, and it's quite a large jump from version 1.
It allows us to use responsive images now and in a way that start to take care of some of the issues discussed above.
Installing and using a polyfill
Polyfills are meant to be set-it-and-forget-it, but because this is an HTML polyfill, you'll either need to make the picture element manually or use some form of HTML shiv to do it for you.
HTML shivs are pretty ubiquitous and come with toolkits such as Modernizr; just verify that picture is supported in whatever shiv you choose.
<!-- Create the actual picture element if you haven't already. --> <script> document.createElement( "picture" ); </script> <!-- Asynchronously load the polyfill. --> <script src="picturefill.js" async></script>
Apart from creating the picture element, you have to link to the script. Using the
async attribute is also recommended, so that Picturefill does not stop your page from loading.
Using PictureFill 2 with
Ok so now we'll look at the syntax that provides the best support and that uses srcset.
It should look familiar because it has the same attributes that we saw when discussing the specification.
<img sizes="(min-width: 40em) 80vw, 100vw” srcset="pic-small.png 400w, pic-medium.png 800w, pic-large.png 1200w" alt="Obama”>
The main difference between this snippet and the specification is the removal of a fallback src attribute, which was intentionally taken out to prevent images from being downloaded twice in unsupported browsers.
The sizes attribute tells the browser of the image's size relative to the viewport. This often gets overlooked because
srcset is the cool kids choice now, but this attribute is equally important.
Using PictureFill 2 with the picture element
The RICG did such a good job with this second version of Picturefill that the syntax of thepicture element should come as no surprise. It matches the specification very closely:
<picture> <source srcset="extralarge.jpg, extralarge.jpg 2x" media="(min-width: 1000px)"> <source srcset="large.jpg, large.jpg 2x" media="(min-width: 800px)"> <source srcset="medium.jpg"> <img srcset="medium.jpg" alt="Cambodia Map"> </picture>
The biggest change between versions 1.0 and 2.0 is the removal of some traditional HTML (divs and spans) and the addition of newer elements (picture and source). Also,
srcset support is built in.
The difference between this and the official picture element is the img fallback. You'll notice here that the img fallback also has
asrcset attribute, instead of a normal src (which is widely supported).
Again, this is to prevent double-downloading. The srcset in the img tag would also cause double-downloading if the browser supports srcset but not picture.
It goes without saying that until a magical one-for-all formula comes along, none of the solutions above will address every possible design eventuality. But that doesn't mean you can't create beautiful, responsive content that works like a dream from desktop to mobile. As with most things, the key is to weigh up which problems you most want to solve - be they legacy content, bandwidth, art direction or others - and start from there. Good luck, and as ever we'd love to hear your thoughts and stories about how you're getting on with responsive images, and with Ghostlab.
About Andi Dysart
Andi is a web developer and designer for Vanamco, a software company based out of Zurich. He works in the trenches developing physical and digital products for the corporate machine and small businesses. When he’s not being a Nerd, he embarks on long expeditions and remote adventures, beer degustation and cooking meat pies.
You know what? Thank you for covering this. Images and responsive-ness were tough to figure out when I first started responsive designs. They just were a pain and really no one covers the ins and outs and the issues with responsive images. This was a great read. I really appreciate it!
It’s tough to use these solutions when you are dealing with clients and CMSs, but it’s nice to have other tools in the pocket. :)
It’s a little bit sad, that you do not cover the newer efforts in respimg polyfillling land. Because there are solutions, which actually make it possible to polyfill with valid markup and be more performant. By simply turning the bad practice to change the src attribute, while the img is still loading it into a performance best practice, called low image quality placeholder. An explanation
It’s a little bit sad, that you do not cover the newer efforts in respimg polyfillling land. Because there are solutions, which actually make it possible to polyfill with valid markup and be more performant. By simply turning the bad practice to change the src attribute, while the img is still loading it into a performance best practice, called low image quality placeholders. An explanation can be found here: https://github.com/aFarkas/respimage/blob/stable/how-respimg-works.md. Here you can find two simple network tests: http://afarkas.github.io/responsive-image-race/ and http://rawgit.com/aFarkas/respimage/stable/cfg/index.html.
The improved picture and srcset polyfill project can be found here: https://github.com/aFarkas/respimage
Additionally, both of your markup examples are not right:
'sizes="100vw, (min-width: 40em) 80vw"'the order of the sizes attribute does matter and you should write it reverse:
'sizes="(min-width: 40em) 80vw, 100vw"'
2. ” A source element without a media and without a type attribute doesn’t make any sense. The
srcset-contentof it can be used directly by the img element. As you already did. So you some kind of unnecessary code repetition.
There is another issue with your markup:
3. Order of source elements matters too: Defining
'media="(min-width: 1000px)"'doesn’t make sense.
Agreed with your valid concern & suggestions.
Since Sencha.io is mentioned, it’s certainly worth mentioning the WURFL Image Tailor too (http://wurfl.io/#wit), which offers comparable features but more reliably. Thanks
Hallo Alexander, it is indeed rather sad that I didn’t come across your polyfill, but now we have some good backlinks for the benefit of the readers. Great work… Check it out people! https://github.com/aFarkas/respimage
thx, in my last comment, I had an error myself. The order of your source elements makes sense, my comment not ;-). But the 1. point i.e.:
'sizes="(min-width: 40em) 80vw, 100vw'is very important. Would be great if you or an admin could change this.