The topic of responsive design is nothing new by now. The topic of responsive images, on the other hand, generates a lot of interesting debates these days. Here is my point of view to the problem of responsive design in general and images in particular.
Possible solutions, for better or worse, pop up like mushrooms after rain that clearly indicates the problem. Most of them have been compiled in this research by Jason Grigsby in September 2011. After that, quite a few new techniques have been proposed. Some great events like Responsive Summit, Standards Next bootcamp have been recently held covering responsive design and responsive images in particular. W3C was not standing aside — the Responsive Images Community Group has got together to discuss some ideas of a client-side solution for the problem.
I had my say on the topic of responsive images some months ago. But even though it works, I still see issues with that. But, let’s check out what other options we have to our disposal at the moment and what to expect in the future.
Server-side responsive images.
Recently Matt Wilcox suggested the Adaptive Images technique that involves Apache configuration and PHP script. This is a cleaner and more flexible solution than the one from Fillament Group. What I really like about it:
- You have flexibility of setting up any custom breaking points, hence have any level of granularity for your responsive images.
- Automatic image sizes generation on request. This one is really cool. PHP script also saves different sizes of the requested images on the server so those are not re-generated on every request.
- Really handy for the CMSes where users don’t have much power over the markup. The technique doesn’t require anything additional to the already existing <img>.
Last point makes the solution a deal breaker for most of the cases. Using existing markup is a real advantage. But I, personally, feel uncomfortable about this solution. The reasons:
- I don’t do PHP.
- Defining image sizes in a server-side script. Image sizes are design-defined so I would feel much more comfortable to define sizes I need on the client-side.
As I have already mentioned, earlier this year, the W3C Responsive Images Community Group has been called. Note that the Group has a potential solution for the responsive images described here, here and demoed here. Though, also note that the group is open for anybody to participate. So do join the group and have your say.
But there is one thing that bugs me in these solutions though — they try to solve just one particular problem. And that particular problem, being responsive images, will inevitably turn into more “responsive” questions. Like what do we do with responsive videos? What about responsive adds if they are not pictures? Period.
But why not to make anything responsive? Not just an image, a video or an add. Anything. Why not to let developers choose the level of flexibility they need? Let’s take an example — a video. Let’s consider the following responsive scenario for it:
- Smallest screens (phones). Only a link to the video so that users decide whether they want to download a video to watch now or not.
- Larger screens (tablets, for example). Show a screenshot (an image) of the video in addition to the link.
- The largest screens (desktop and up). Show video right away.
Pretty reasonable scenario as for me. And it shouldn’t be like putting all of these elements into HTML letting CSS manage what element to show at a certain moment. This would completely vanish the responsive idea of your design in general and mobile-first approach in particular — mobile browsers would still need to download both, image and video, no matter whether they are visible or not. I hope it’s clear why it is impractical.
What I mean is a certain way that would render required DOM elements only when they are needed. In my post to the W3C Responsive Images Community Group I proposed the following markup to tackle the problem of responsive images:
<picture> <source query="(min-width:420px) and (max-width: 767px)"> <img src="http://dev.null/small.jpg" alt="Alternative text for capable browsers wider than 420 but narrower than 768px" /> </source> <source query="(min-width:768px)"> <img src="http://dev.null/large.jpg" alt="Alternative text for capable browsers wider than 768px" /> </source> <img src="http://dev.null" alt="Alternative text for browsers not understanding CSS media queries or screens smaller than 420px" /> </picture>
Once again, snippet above is supposed to show the responsive images, hence the wrapping <picture> element. Note that this markup is a prototype that can not even be properly polyfilled at the moment — modern browsers will pre-fetch all the images on load anyway. The post contains an explanation of how this markup should potentially work in the browsers.
In order to make it less attached to the images, we can get rid of the <picture> element and have a set of bare responsive elements. Though the problem is obvious — <source> element is already used within <audio> and <video> with different semantic meaning. So we, probably, need another element like <responsive> To reflect the aforementioned video scenario we could do something like:
<responsive query="(max-width:419px)"> <a href="view_video">Watch the video</a> </responsive> <responsive query="(min-width:420px) and (max-width:1023px)"> <img src="poster.jpg" alt="Screenshot of the video" /> <a href="view_video">Watch the video</a> </responsive> <responsive query="(min-width:1024px)"> <video preload="metadata"> <source src="video.mp4" type="video/mp4" /> <source src="video.ogv" type="video/ogv" /> </video> </responsive>
And now we are approaching the core — <responsive> or any other wrapping element is not essential by itself and does not provide any semantic meaning either. What we really need is the new attribute like
query above that accepts CSS media query syntax and can be set on any already existing tag. But in this particular example, the containing element is really just a wrapper and only it’s content matters. So <div> would be the best candidate for this wrapping role. Let’s check how our snippet would look like in this case:
<div query="(max-width:419px)"> <a href="view_video">Watch the video</a> </div> <div query="(min-width:420px) and (max-width:1023px)"> <img src="poster.jpg" alt="Screenshot of the video" /> <a href="view_video">Watch the video</a> </div> <div query="(min-width:1024px)"> <video preload="metadata"> <source src="video.mp4" type="video/mp4" /> <source src="video.ogv" type="video/ogv" /> </video> </div>