Cloud Four Blog

Technical notes, War stories and anecdotes

8 Guidelines and 1 Rule for Responsive Images

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.

8 Guidelines for Responsive Images

1. Use vector-based images or font icons whenever you can

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.

Resources

2. Encourage people to upload the highest quality source possible

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.

3. Provide an automatic image resizing and compression service

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.

4. Images can be resized to any size with URL parameters

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"
/>

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.

5. Provide automated output of your image markup

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},
]
}

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.

6. Provide a way to override resized images for art direction needs

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.

7. Integrate image compression best practices

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.

8. Bonus: Detect support for WebP image format and use it

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.

The one and only rule for responsive images:

Plan for the fact that whatever you implement will be deprecated

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.

23 Comments on “8 Guidelines and 1 Rule for Responsive Images”

  1. Fantastic article and insights!

  2. Great article, thanks! I have a little resizing script I use to resize images on the fly, adding WebP support is a great idea… might as well!

  3. Andy Hoffman says:

    Great, well-written content. Thank you.

  4. gondo says:

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

    • The article makes a good point, but SVG is still extremely convenient for quick implementations…

    • Jason Grigsby says:

      @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.

  5. Tom D says:

    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.

  6. Joe Snell says:

    Great resource Jason! Not surprised, you nailed it. Now the tough part – implementation!

  7. 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.

  8. 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.

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

      • Remi Grumeau says:

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

        • Jason Grigsby says:

          @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.

  9. kindly says:

    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!

    • Jason Grigsby says:

      @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.

  10. Martin says:

    Great article, thank you. Now I have to put it in to practise.

  11. Haeren says:

    Great summary! We’re working on a major re-modeling of our 9 news sites so this blog post is definently relevant for us!

  12. RWD is the solution for everything says:

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

    • Jason Grigsby says:

      @RWD Anonymous Person

      What are you talking about? That is exactly the way both Akamai’s Edge Image Manipulation and Sencha.io SRC works.

      You declare width in the URL and the server resizes appropriately. And it works on every device in existence because the device has no idea that there is any server logic going on.

    • Niccolò Brogi says:

      There has to be a server-side script that takes the parameters and resizes the images, of course…

  13. Ali says:

    really awesome responsive images tutorial, i was using few of plugins for solving this problem.

  14. Carlo Roosen says:

    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?

    • Jason Grigsby says:

      You’ve got the concept correct. The idea is something similar to JPEG 2000 or possibly using progressive JPEGs in a way they’ve never been used before.

      As far as plans are concerned, I don’t know of any thing solid. Here’s what I believe the current state of things are:

      * JPEG 2000 is considered patent encumbered so people don’t seem to be working on it.
      * Progressive JPEG might work. Some folks are testing this idea out.
      * Any new format or an old format used in a new way (e.g., Progressive JPEG that only downloads portions of the file) will need some sort of markup change to provide a backwards compatible option.

      If we did have something like this, the challenge will again be trying to strike a balance between the pre-parser and image downloading. I’ve written about this challenge at http://blog.cloudfour.com/what-a-holy-grail-image-format-would-mean-for-the-browsers-lookahead-pre-parser/.

      Basically, it is the unicorn format. It sounds awesome, but it doesn’t exist (yet?).