The simplicity of Adaptive Images

29 November 2013

I was lucky enough recently to work alongside top digital designers John and Rachel Oxton-King, a.k.a. Mr and Mrs OK, as they produced a wonderful new "mobile friendly" website for the Rationalist Association. As a back-end developer primarily, this was my first major experience with mobile first responsive web design.

A key aspect of "responsiveness" is that images are not given a width or height, but simply styled with max-width: 100%; so that they can expand or contract according to the available device width. This allows the design to be fluid whilst maintaining proportions at different screen sizes. You don't get huge fixed size images pushing everything else out of the way on smaller devices. Everything scales nicely.

What a waste

Of course the physical image still has to be as large as it needs to be on the largest supported screen. And if you want it to look good on the latest higher pixel density "retina" displays, it'll need to be even bigger than that.

While it's great that users of small mobile devices can expect a design that's laid out sensibly for them without having to zoom in on a 960 pixel desktop layout, wouldn't it be even better if they weren't forced to download those enormous images which will only be displayed at a fraction of their original size? After all, the more portable the device the more likely it is to be on a slow, bandwidth-capped mobile data plan, with those precious included MBs being gobbled up for no good reason by your site's desktop/retina-ready images.

The bandwidth cost at the server end is equally unnecessary.

<picture> this

There's clearly a need for the image files themselves to be "responsive", not just the design, and for a while now various clever folk have been trying to agree on how to make browsers handle this but with apparently little progress.

Meantime, the need to stop wasting everyone's bandwidth is urgent, and while we wait for a standardised client-side solution, I'd like to commend the server-side approach I chose to adopt for the aforementioned project: Matt Wilcox's Adaptive Images.

No front-end changes required

Instead of trying to persuade browsers to request differently sized images through javascript polyfills or other client-side trickery, Adaptive Images sorts it all out at the server end. This means no changes to your HTML are needed apart from a single line of JS in the <head> to sense the width of the device and its pixel density.

When an image is requested—via a regular img tag—the server will then do its best to create and deliver a version that closely matches the device width—one that's no bigger than it needs to be for that particular screen size.

Simple for the front-end developer, and simple for the CMS and its users who only need to supply a single (large) source image.

Adaptive Images for ColdFusion CFML

Matt's original implementation uses PHP to do the on-the-fly sensing and resizing magic, and a legitimate objection is that handling all of a site's images is a heavy burden to place on the application server—a task more efficiently handled by the web server.

I shared this concern initially, but the potential rewards were too appealing. So I set about building a ColdFusion port, taking inspiration from Raymond Camden's earlier work and resolving to increase the focus on performance.

The result is AdaptiveImages for CF9.0.1+ and Railo 4.2+.

Basic instructions and configuration options are in the ReadMe.

Although only just made public on GitHub, the code has been in production use for a year (hence the v1.0.0 release), during which time there has been lower than expected bandwidth usage on the Rationalist Association site, with no noticeable performance issues. Even under load from a tweet by @StephenFry.

Update 1 October 2014

The test suite has now been adapted for Railo 4.2 and all tests pass.


  • Formatting comments: See this list of formatting tags you can use in your comments.
  • Want to paste code? Enclose within <pre><code> tags for syntax higlighting and better formatting and if possible use script. If your code includes "self-closing" tags, such as <cfargument>, you must add an explicit closing tag, otherwise it is likely to be mangled by the Disqus parser.
Back to the top