At Google I/O last week, I was hoping to hear Google’s thoughts on responsive images. Every developer I speak to wonders how to send the right image size to browsers, Google is obsessed with performance, Peter Beverloo and Paul Kinlan were explicit in their talk Mobile HTML: The Future of Your Sites that web sites should request the correctly-sized images. But how?
The <picture> element seems to be at an impasse; no-one from Google showed any enthusiasm (nor does any other browser vendor, seemingly). That’s OK; when I dreamed it up 18 months ago it was a strawman to get the conversation going in standards groups (I’d previously been told that there was no need for any standard, as everyone would have huge devices on reliable, fast wifi in the future).
We have the
srcset attribute, with its wildly unintutive syntax, “ready for first implementation”, so supported nowhere yet. It’s disliked by oiks who actually make web sites and fails to satisfy the art direction use case that 27% of those oiks currently polyfill to address.
Google has proposed a Client Hints header with device resolution, viewport size, touch-enabled flag etc. The idea is that the server generates lots of different sizes of foo.png, and when a request comes for foo.png, the server looks at the Client Hints and sends the most appropriate size. Opera (and soon, Chrome) announces that it accepts webP images, so the server could intercept requests for foo.png and send foo.webp in its place for conforming browsers, thereby reducing bandwidth.
This server-side negotiation will be great for legacy pages as it means source code doesn’t need to be touched. I’ve heard it also touted as being much simpler to author, but I wonder about that; HTML isn’t hard to write, while implementing server-side image resizing and transcoding, intercepting headers, doing the negotiation and setting cache control is much harder for an HTML wrangler than writing HTML is. It also assumes everyone has full access to the server. Don’t forget that some uses of HTML (for example, ebooks) have no server.
But those are all for the future. What can you do now? Clever, but ultimately unsatisfying workarounds.
Firstly, have <img> with a dummy source, then replace the
Alternatively, make your images into single-frame
<video>s, and take advantage of media queries on the child
<source> element to send differently sized images. Ian Devlin dreamed this up, and it’s evil genius – except that file sizes increase and
<video> doesn’t have an alt attribute, so the “images” are therefore inaccessible.
A similarly inaccessible technique for webkit browsers is simply to use a
<div> element instead of
<img> and set an image-set background-image in CSS. Don’t do this; it’s inaccessible, and is single-engine.
The current best way is brilliant albeit somewhat hacky: Estelle Weyl‘s clown car technique. This uses a data-encoded SVG file, embedded using an <object> element. Unfortunately, there’s nowhere to hang alt text, and right-clicking to “save as” doesn’t behave as expected.
Images are central to the web; we need a declarative HTML method to achieve them in our multi-device world.
I’ve done my part in suggesting a strawman, and although cleverer minds than mine tell me it’s a bad solution, in a year and a half no-one has told me what a good one looks like.