One of the big 3 requirements for responsive design is flexible images and media. On the surface it seems like an easy thing to do. You remove width and height attributes on images, set their max-width to 100% and call it a day. Beneath the surface there’s a lot more we need to consider.
The Problem with Images in a Responsive World
When the Filament Group was redeveloping the Boston Globe website last year they too added max-width to keep images flexibly inside their containers. The problem though, is in order to do that you need to create images as large as they can possibly be. You end up with an image with the maximum dimensions and maximum file size.
Unfortunately for all cases except when the maximum image is needed, that’s wasteful. Smartphones and tablets connecting over a cell network don’t need an image larger than they can display. It just easts bandwidth.
Even if bandwidth weren’t an issue you still have to consider if the same image works at very different sizes. What’s communicated in the details of a 1000px image might be lost when that image is 300px. Better than resizing, might be to crop the image or use an entirely different one in its place.
And let’s not forget about high resolution displays. With Apple introducing retina display across more devices we want our images to contain more pixels. Other devices will likely follow Apple’s high-res lead, though perhaps with different pixel densities.
We can’t simply preload all the different images we might use, since it defeats the whole point. We’re trying to reduce bandwidth needs, not increase them.
We need a greater ability to serve device and context appropriate images and media.
3 Paths to Solution
There are several paths being considered or explored to solve these problems. Chris Coyier summed them up nicely in his post on responsive images. We can:
- create a new (html) element
- create a new image format
- fix the problem with other technologies
Let’s take a look at the solutions in each path.
Create a New Element (or Attribute)
This is already in the works, though how it’s proceeded has been an issue in itself. Without getting into the controversy there are basically two proposals, one coming from the web development industry, and the other coming from the browser makers.
The proposal from the develop side creates a new picture element similar to the existing video element. Inside is another element, source, along with the usual img element and it should be relatively easy to understand what’s going on if you look at the code below.
1 2 3 4 5
<picture alt="image description"> <source src="/path/to/medium-image.png" media="(min-width: 600px)"> <source src="/path/to/large-image.png" media="(min-width: 800px)"> <img src="/path/to/mobile-image.png" alt="image description"> </picture>
The img element is the default so what’s in its src gets displayed by default. Above it the two source elements point to different images that would be displayed based on the different media queries. If it comes across as easy to use, that’s because it is. It’s a developer friendly solution.
Scott Jehl created a polyfill for the picture element so you can use it now.
1 2 3 4
<img src="path-to-default-image.jpg" alt="" srcset="path-to-default-image.jpg 600w 200h 1x, path-to-another-image.jpg 600w 200h 2x, path-to-a-third-image.jpg 200w 200h">
Let’s look at the first value in the srcset attribute above.
path-to-another-image.jpg 600w 200h 2x
- path-to-another-image.jpg should be self explanatory. It’s the image we’ll use when the following conditions are met.
- 600w and 200h are equivalent to min width and height media queries.
- 2x represents the pixel density. 2x is twice the normal density.
So here when the browser can handle a 2x image and is at least 600px wide and 200px wide we’ll serve it the image specified.
This solution works well from a browser maker’s viewpoint. It can better algorithmically determine device capabilities around pixel density.
Again I’ll stay clear of the controversy, except to say each syntax has valid reasoning for why it should be the standard. If you want to know more about the controversy, click some of the links in this section. They’ll lead you pretty quickly to it.
As someone who develops websites I like the syntax of the picture element, however I think given the backing we’re more likely to see something like the srcset syntax. The discussion is still ongoing and most seems open to incorporate the best of both.
I recently listened to a couple of podcasts discussing all of the above.
- SitePoint Podcast #168: Secret Src with Jeremy Keith
- The Web Ahead: Responsive Images with Mat Marquis
A New Image Format
This one should be simpler to explain. Christopher Schmitt is calling for a new responsive image format. The new format would basically be a container for several different sized versions of itself within. A 100k file might have a 75k version, a 20k version, and a 5k version of the same image inside.
In a way it would work like .mp3 files that store both song and meta information about the song. Here though instead of meta information the new format would store different variations of the image.
A standard set of rules would determine which of the inside images is the one that gets served to the device. Where the code is concerned this is as simple as it gets. Nothing changes, other than using a new image extension.
The downside is we’d be giving up some control. The new image format itself would determine the rules for which version gets delivered and when. It also wouldn’t be backwards compatible to browsers that don’t understand the new format.
Both of the options above, while relatively simple, aren’t here yet. If you want to serve the most appropriate image to each device right now, you’re going to have to use one of the other methods. There are quite a few of them. Too many to try to describe them all in one section of a post.
Many follow the lead of the Filament Group. Their responsive images method with the Boston Globe took the following approach.
- Markup — defaults to the image for mobile devices
It didn’t quite work as well as hoped, though it pointed the way and gave everyone something to build on.
Most of the methods that have come after generally share similar characteristics. They serve the mobile image by default and then attempt to detect device characteristics before serving the most appropriate image.
Chris Coyier and Christopher Schmitt created a spreadsheet with different techniques along with information to help you decide which is best for your project. Chris also wrote a post based on the spreadsheet to answer the question, which responsive images solution should you use?
I’ll mention a few of the methods below with a quick word about each so you can get a feel for how they work. You should really check Chris’ post and the spreadsheet for the details on these and many other methods.
Depending on what it finds, it then requests the appropriate image for display.
Images redux uses a blank 1×1 GIF (converted to base64). It sets the background of this .gif to whatever image needs to be served and also sets the background-size property to the value contain.
Because the image you want to display is set with css, it can be changed via media queries.
Image above via CSS Tricks
Adaptive images was inspired by the original work on the Filament Group did when redesigning the Boston Globe site. It requires Apache 2, PHP 5.x, and GD lib, though these are all fairly common.
HiSRC is a jQuery plugin that detects network speed and resolution capabilities. By default the smallest image is served, but if HiSRC detects the device more capable it serves a different image.
Conditionally Loading Content is a post from Jeremy Keith, where he described how he was serving different images to different devices. It’s a custom solution where Jeremy is testing for the width of the viewport. Conditional CSS is a follow up post presenting solutions from others that improved the initial solution.
The first step in making your images responsive is to make them flexible. Remove width and height attributes and setting their max-width to 100%. It doesn’t solve all problems though. The main one it leaves is that we’re required to create a single large image that isn’t best to serve to all devices.
In time a couple of things will happen. Bandwidth will increase to the point where this is mostly a non-issue (at least when compared to the next bandwidth issue) and we’ll have new html syntax to tell browsers which image to serve. Perhaps we’ll also get a new image format that can deal with the issue for us.
At the moment we have to choose from a variety of techniques that do similar things. They serve a mobile version of the image and test to see if the device being used can handle a bigger image. If so the script replaces the mobile image with the bigger one.
As hard as it might be to believe, there’s still more to say in regards to images and responsive design. I’ll save that talk for next time where we’ll look at vector images along with a few things that didn’t fit into this post.
I’ll leave you today with a short series of posts about responsive images from Jason Grigsby.