On Responsive Images

Avatar of Chris Coyier
Chris Coyier on (Updated on )

📣 Freelancers, Developers, and Part-Time Agency Owners: Kickstart Your Own Digital Agency with UACADEMY Launch by UGURUS 📣

There is a real need for serving media that is appropriate for the device and circumstance, since we know so little about any particular web request. I recently posted a blog post with so many images on it the page weighed in at 2.29 MB. I should have posted a warning when I tweeted it: “Don’t click this if on a 3G network, it probably take forever, just check it out when you get home.”

Ideally, all those images I served up could have had a lower-res version of themselves that display on browsers with smaller browser window sizes and/or slower connection speeds. Even in cutting edge browsers, there is no native way to do this yet. So it’s a good time to start talking about how we want that to work as web builders. Perhaps we can influence how the spec shapes up.

Let’s limit this conversation to inline raster images. As in, the things today served as <img>. As I see it there are three paths we can go.

  1. Create new element that exists just to serve this problem.
  2. Create a new image format designed to solve this problem.
  3. Do nothing, fix our problems with other technologies.

Each of them has advantages and disadvantages. Let’s look at each.

Create New Element

The most likely candiate is <picture> as being discussed here in the W3C community. Scott Jehl has a JavaScript polyfill that mimics what it’s functionality would be. The syntax would be:

<picture alt="description of image">

  <!-- low-res, default -->
  <source src="small.jpg">

  <!-- med-res -->
  <source src="medium.jpg" media="(min-width: 400px)">

  <!-- high-res -->
  <source src="large.jpg" media="(min-width: 800px)">

  <!-- Fallback content -->
  <img src="small.jpg" alt="description of image">

</picture>

Advantages

  • Mimics other media syntax like <video> and <audio>, which makes sense.
  • The fallback makes it backwards-compatible with browsers that don’t support it, which is extremely important. We can’t have images that just don’t work in older browsers.
  • Gives us web authors the control to show exactly what we want under situations we specify.

Disadvantages

  • It’s a whole lot more complicated than <img>. Harder to teach, harder to learn, more code to write. Easy to screw up.
  • Muddies the water of CSS and HTML a bit, by bringing the media query syntax into HTML.
  • Similar issues to why inline styles are bad. Makes future updates more difficult. Not a reusable abstraction.

New Image Format

The impetus behind this blog post came from conversations I with Christopher Schmitt and a blog post he wrote. Christopher is of the opinion that a new image format is the ideal solution.

This new image format would essentially have multiple versions of itself inside of it.

Which image is delivered by a program like a web browser is a determination that can be made by a virtual handshake between the browser and the web server.

So perhaps the file is 800k all together, but within it is four different versions of itself: 500k, 200k, 50k, 10k. Through some kind of standardized set of rules, one of those four images would come across and be displayed by the browser.

Seem like a fantasy? There is already an image format like this called FlashPix, which handles even more drastic versioning. Think new image formats are impossible to implement? WebP is gaining support at a decent pace.

Ultimately the syntax would remain just as it is now:

<img src="unicorn.rpng" alt="fancy unicorn">

I just made up that file extension, but “responsive PNG” would be fine with me.

Christopher likes this approach because

it allows the continued use of the IMG element which is ingrained into the bones, the very marrow, of the Web.

I like that thinking. No need to turn our backs on an element which has worked so well for so long. But of course we wouldn’t. There is no need to replace <img>, only build upon it and offer alternatives.

Advantages

  • Keeps the syntax simple. Works the same way it always has.
  • Keeps authoring simple as well. One file, not multiple. Adoption would probably be quicker and more people would actually do it (less people would make 4 versions of every image and hand craft queries to serve them).

Disadvantages

  • Possible loss of control. In order to keep things simple, the image format would do the logic of what exactly gets served. Will it always make the right call? What does it factor in? Parent container width? Network connection speed? Pixel density? A combo?
  • Not backwards-compatible. What happens in browsers that don’t support the new format?

Other Technologies

We could certainly lean on JavaScript to help us here. It could help us with the new image format, for one. We would use regular old png’s and jpg’s in our <img> and hot-swap the src with the new format for a while until the new format has ubiquitous support. A little heavy-handed perhaps, but workable.

And if it can do that, maybe we should just let it solve the entire problem. JavaScript is able to do all the “tests” we likely need it to do (e.g. window size testing, network speed testing), and it could be in charge of swapping our the src of our images with more appropriate ones. The foresight.js by Adam Bradley library is doing that already. Perhaps that is what JavaScript is for and we don’t need to interfere.

Think the client-side nature of JavaScript isn’t ideal? There are a couple of solutions that bring things server-side.

Adaptive Images by Matt Wilcox is a ridiculously clever solution that using a tiny sprinkle of JS just to measure the current screen size and set a cookie, and then all requests for images are routed through some PHP which determines which version of an image to server, appropriate to screen size.

Sencha.io Src is another solution that is completely JavaScript-free. It does UA sniffing to determine the device and makes the call on what size image to serve up based on that. You simply prefix the src of the image with Sencha’s service URL:

<img src='//src.sencha.io/http://mywebsite.com/images/unicorn-hires.jpg' alt="unicorn" />

That’s the simplest possible usage, it can get a lot fancier than that. It’s a third-party Beta service though, so be aware of the inherit concerns of that (e.g. they go down, your images don’t load). I imagine it will ultimately be a paid service.

Advantages

  • We don’t rock the boat of standards.
  • No waiting for browsers to catch up on supporting anything new.

Disadvantages

  • Is this just ignoring the problem? Aren’t standards supposed to help with real problems?
  • The code needed to do this right is heavy-handed.

Where I Land

Relying on older technology and hacks isn’t enough for me, but I can’t decide whether I prefer a new format or new syntax. Maybe both? Maybe a hybrid? I feel like the syntax is more likely because there is more discussion about that. A format is a much taller order and I’ve heard no whispers of active development on anything like that.

It’ll be a fun day when I can update this blog post with “official” best practices!

Related