Skip to main content

8 Guidelines and 1 Rule for Responsive Images

By Jason Grigsby

Published on April 2nd, 2013

Topics

I recently had the opportunity to work with a company that is moving to a responsive design and has over 800,000 images on their site. These images come from all over the world. I learned a lot about what it means to tackle images in a responsive design on a large scale.

One of the big lessons is that we spend a lot of time discussing what the frontend solutions for responsive images should be—the new picture element or srcset or a magical new image format—and little time discussing how backend systems and human processes might need to change.

The company I consulted has procedures in place for images. These processes include having the images enhanced if necessary, cropped to fit, resized, and then saved in a web optimized format to fit exactly how the image is used on the page. That process makes a lot of sense for the current fixed width site, but will break down when the site becomes responsive.

These conversations led me to document my ideal scenario. If I could wave a magic wand for organizations, what would I put in place for their responsive images processes and tools?

The result was eight guidelines and one rule for responsive images.

SVG logo Wherever possible, avoid the problems of pixel-based images by using vector alternatives.

SVG has decent browser support. The Filament Group has a project called Grunticon that will generate SVG and fallback PNGs along with the CSS necessary for you.

Icon fonts are also a big win with fairly wide support. You can create your own fonts with just the icons you need. A bunch of images can be contained in a single HTTP Request which means icon fonts provide similar performance benefits as CSS sprites used to.

Just make sure you use progressive enhancement for your icon fonts and use them in an accessible manner.

As prices for high-density screens go down, they are starting to show up in more devices and at larger sizes. It isn’t hard to imagine Apple releasing Retina Cinema Displays in the not so distant future.

Having content authors upload the highest quality image they have into whatever system you use to manage content means that you’ll be ready for whatever resolutions are needed in the future. Managing and keeping track of these assets will make life easier if you redesign the site in the future.

Storing the highest quality source files will likely mean an increase in storage requirements, but storage is cheap these days.

If you have a lot of images on your site, it will no longer make sense to resize them and optimize them for the web by hand.

White House Official Portrait of Michelle Obama resized at three different sizes

For example, if the client I was consulting with had decided that they needed three responsive image breakpoints, that would mean three times their current 800,000 images. And that is just standard definition. Multiple the number of images by two if you want to support retina displays. The end result would be 4.8 million images.

Now they wouldn’t have to do all the images at one time, but it still a lot of work. So instead, companies need to build or buy centralized systems that will resize and compress images.

That image resizing service? It should be able to take information that identifies a source image as well as the measurements that the image is needed at and resize the image on the fly.

A good example of a service like this is Sencha SRC. See how you can declare in the URL just the width or the height and the service will resize the image proportionately. That’s what you want.

<img
  src="http://src.sencha.io/320/http://sencha.com/files/u.jpg"
  alt="My constrained image"
/>
Code language: HTML, XML (xml)

If you’re an Akamai customer, the Akamai Edge Image Manipulation service might do the trick for you. It is currently in beta and offers a ton of useful functionality.

Whatever you do, you’ll want to make sure you’re providing smart caching and not breaking external caches.

It doesn’t really matter what solution you decide to use in your markup for responsive images. My personal preference is the PictureFill solution, but there are many options to choose from.

But no matter what solution you pick, you should centralize the markup so that it will be easier to change in the future.

For example, in your templates, you might not put any direct HTML, but instead define a series of source images and breakpoints like so:

{
"source":"/source.jpg",
"breakpoints": [
{ "max-width":"30em","pixel-density":1,"width":360px}, 
{ "max-width":"30em","pixel-density":2,"width":720px},
{ "max-width":"30em","pixel-density":1,"width":800px},
{ "max-width":"30em","pixel-density":2,"width":1600px},
{ "pixel-density":1,"width":800px},
{ "pixel-density":2,"width":1600px},
]
}
Code language: HTML, XML (xml)

And then pass that to a central function that would output the correct PictureFill markup or whatever markup you’re going to use.

Don’t get hung up on the syntax or the data contained in the example. The key is that by centralizing image markup in a function, you can change it quickly when the standards evolve.

For most sites, the most important use of responsive images will be to provide different resolutions of images based on the size that the image is used on the page at a particular viewport size. That is what we call the resolution switching use case.

Occasionally you will find that simply resizing an image isn’t sufficient. A smaller version of the same image becomes unrecognizable.

Obama speaking at an auto factory. At the large size, Obama is easily recognizable.

But at a smaller size, the image can be hard to discern.

The same image of Obama, but this time it is so small that you can barely make out who he is

If you make changes to the image source at smaller sizes, the image can be easier to see.

The photo has been cropped so that Obama is easier to see at the small size

This is what we call the art direction use case.

Another place where you may need art direction is for images that contain a combination of text and photography. Ideally, you can separate the photography from the text, but sometimes you can’t get the control you need and when you shrink the image, the text becomes unreadable.

For this recent project, we were able to identify a handful of templates where the need for art direction might be necessary. For those templates, the CMS will be modified to allow authors to upload different sources and define at what breakpoints those sources should be used.

If you’re going to centralize your image resizing as a service, this is the perfect opportunity to incorporate the best tools in image compression.

Google has some great information on ways to optimize images. It should also go without saying that you need to set far future expires headers for your images.

As long as you’re centralizing image delivery, why not look into supporting WebP?

The average WebP file size is 25% – 34% smaller compared to JPEG file size. WebP compresses 34% better than libpng, and 26% better than pngout for loseless images.

Google wrote recently about how they’re checking for WebP support when an image is requested and automatically serving up the WebP alternative if the browser is capable of displaying that image.

Ideally, browsers would simply support WebP, but in the meantime, there are some performance gains that could be had and it might not add too much to your image resizing service to support it.

No one knows what the future of responsive images holds. A few years from now, we will probably look back on the hacks we’re using and laugh at our naivety.

The one thing we can be certain about is that we’re going to need to replace what we implement now when standards catch up with responsive images.

So whatever you build, make sure it is flexible and can be changed easily when the ultimate solution for responsive images becomes apparent.

Comments

gondo said:

hi
im still not convinced about the SVG. just a side note about vector graphic http://dcurt.is/pixel-fitting

Replies to gondo

Jason Grigsby (Article Author ) replied:

@gondo: Thanks for sharing that article. That was a great read.

That said, I don’t think it applies in this case. Responsive images are by definition going to be resized by the browser. That’s the whole point and the reason why we run into all of these problems.

So even if we took the steps that are in that article to manually specify the pixels for a specific size, that would only work if the image was only ever displayed at that size and the browser never resized it.

For the scenarios I’m talking about here, we’re choosing between having the browser resize something that is pixel-based and having the browser resize something that is vector-based.

The computer resizing and rendering is a given regardless of whether it is vector or pixels. And when that is the case, there is no question in my mind that vector is the superior choice.

Tom D said:

Great article summarizing the challenges and best practices for handling responsive images.

Another great option for serving dynamically generated images is LiquidPixels (http://www.liquidpixels.com/). They can resize images on the server, so using media queries or a simple js snippet will allow you to send the perfectly sized (and correct DPI for retina screens) images for every screen size.

Steve Souders said:

Great advice. So sad that such a basic need is so far from a feasible solution, but also a great opportunity for future work.

I love Sencha SRC and wanted to mention you can kinda combine guidelines 3&4 using Sencha SRC as a remote service. For example, I always need to resize images to fit my narrow blog post width of 480px, so I wrote this bash function (not sure if the code structure will maintain in the final comment):

resizeimg ()
{
if [ "" = "$3" ]; then
echo "Usage: resizeimg imageUrl width outputfile";
else
local imageUrl=$1;
local width=$2;
local outputfile=$3;
curl -o $outputfile http://src.sencha.io/$width/$imageUrl;
fi
}

With that function I can just do the following on the commandline:

resizeimg http://stevesouders.com/images/bigchart.png 480 bigchart480.png

Obviously, this could easily be incorporated into a build script or cronjob.

Ilya Grigorik said:

Jason, one thing to add: don’t forget the numerous open-source solutions for handling image optimization and resizing! One good example: mod_pagespeed (Apache module), ngx_pagespeed (Nginx module), both of which are powered by the same underlying PageSpeed code (also open-source).

Both of the above will help automate image optimization for you:
– automatically determine the optimal image format (JPEG, PNG, WebP)
– automatically optimize each image format (metadata stripping, etc)
– automatically serve WebP to user-agents that support it
– automatically resize images based on HTML markup

With above in place, you can specify the right image size directly in your HTML markup (or inline CSS), and not worry about the rest. The server will parse the markup and rescale the image to the appropriate size on the fly (and cache it).

For a deep-dive: https://developers.google.com/speed/docs/mod_pagespeed/filter-image-optimize

As you pointed out, given the diversity of screen sizes, image formats, etc.. automation is key. Finally, if you’re looking for a hosted solution, then PageSpeed Service offers all of the same logic, but running on Google’s servers.

Replies to Ilya Grigorik

Niccolò Brogi replied:

That’s awesome! So, for retina you would just double the width in the img tag..?

Replies to Niccolò Brogi
Remi Grumeau replied:

You’ll get a better result with a very strongly compressed (30%) JPEG at twice the size than real size at 70%.

Replies to Remi Grumeau
Jason Grigsby (Article Author ) replied:

@Remi I remain skeptical of the “Compressive Images” techniques.
http://blog.netvlies.nl/design-interactie/retina-revolution/
http://filamentgroup.com/lab/rwd_img_compression/

My primary concern is that we have run into issues in the past with images exceeding memory limitations of older browsers. I once had a CSS Sprite not showing up on iPhones because the decompressed size of the image exceeded Mobile Safari’s limits on the resolution of images.

So on the one hand, I am fascinated by the technique. It is a crazy, cool hack. I’d love to see it be the solution going forward.

On the other hand, I can’t recommend that any of our clients implement it on a production site until a more comprehensive study has been done of its implications on older browsers.

It’s one thing to test a single example compressive image. It will be another thing entirely when someone implements a page full of compressive images—each image’s true resolution and memory footprint twice the size of what it would be with a regularly sized and quality image.

I really want it to work, but see it as too risky to recommend until someone else validates the approach at a larger scale.

kindly said:

webp maybe compresses 25% better than libpng, but so does ImageOptim.

And tinypng.org compresses PNG by 60%.

Don’t pollute the web with browser-sniffed Chrome-only format (do you use JPEG-XR for IE too?)

Just use standard formats well!

Replies to kindly

Jason Grigsby (Article Author ) replied:

@kindly Using WebP is no different than content negotiation. The client declares what it supports and if the server is smart enough to do something with that information, the user gets a faster experience.

The example Google gave continued to have JPGs and PNGs in the markup. The only thing that changed was that when the request for that JPG or PNG came in, the server would swap out a WebP image if it was supported.

This no different than supporting SPDY if the client says it can handle SPDY.

As far as broader support is concerned, Opera has supported WebP for awhile. Mozilla has reopened the bug on supporting WebP and is working on implementing it:
https://bugzilla.mozilla.org/show_bug.cgi?id=856375

In addition, it sounds like both Chrome and Mozilla are looking at adding explicit declarations of support image types to the request headers to make it easier for servers to handle different image formats. See:

http://www.igvita.com/2012/12/18/deploying-new-image-formats-on-the-web/
https://code.google.com/p/chromium/issues/detail?id=169182

So yes, Google has been a big proponent of this, but what I describe here is:

1. Content negotiation that speeds up things for users and doesn’t pollute anything.
2. Anticipates where standards are going given the momentum behind WebP right now.
3. It was a bonus anyways. The client I was working with decided against doing this at this point because it wasn’t practical for their environment.

RWD is the solution for everything said:

and did you try 4. Images can be resized to any size with URL parameters? Thats never works on real devices!

Carlo Roosen said:

Hi, you briefly mention a “magical new image format”. Would that be an image format that progressively enhances while it is uploading, and where the browser stops further downloading when the quality is enough for its screensize? Seems to me the most logical path to go. Are there plans for such an image format?