Grow your CSS skills. Land your dream job.

Why Responsive Images Is So Hard

Published by Chris Coyier

Perhaps you've been keeping up on the responsive images #hotdrama? If you have no idea what "responsive images" means, it means serving different images under different circumstances. How to do that and what those circumstances are vary widely.

If you aren't caught up, here's some linkage. Bruce Lawson did an end of the year report. This provides a nice history of the work behind trying to standardize a solution. Mat Marquis wrote up a succinct summary of where all the major browser vendors are at (no consensus). Tim Kadlec has a nice summary of the situation. Dave Rupert has been talking about it as well.

An important thing to understand here: all of this talk is focused around images in the HTML. Content images.

This problem is largely solved in CSS. If the image being added to the page doesn't need to be in the markup, you can use media queries in CSS to handle the conditions and change the image accordingly.

/* Look ma, responsive images */

body {
  background: url(mountains-small.jpg);
}
@media (min-width: 500px) {
  body {
    background: url(mountains-medium.jpg);
  }
}
@media (min-width: 800px) {
  body {
    background: url(mountains-large.jpg);
  }
}

Of course, sometimes images do need to be in the markup. That's what <picture> and srcset and srcN are all trying to solve. It's a tough job. The solutions needs to:

  • Deliver only one final src
  • Be semantic
  • Be accessible
  • Be backwards-compatible
  • Accomodate art-direction
  • Accomodate all the conditions we deem important
  • Accomodate future conditions we aren't even thinking about yet
  • Work independently of any other language/technology
  • Be agreeable to authors AND standards people AND browser vendor people

Why is it so hard for everyone to agree? Nobody involved is evil. Nobody is is sitting in a dark castle tower laughing maniacally. Nobody is intentionally delaying a solution. At least as far as I know.

I suspect the problem is the browser vendor people are trying to:

  1. Make educated guesses as to the difficultly of implementation.
  2. Make educated guesses on what the future would be like with the particular implementations in place.

While authors:

  1. Are pretty sure we know what we need.
  2. Are concerned about our needs on our projects and, while we care about the web as a whole, have less perspective on that.

And standards people need to:

  1. Make sure nothing gets broken.
  2. Cover as many needs as possible.
  3. Also make educated guesses on what the future would be like with the particular implementations in place.

And after they have make all those guesses, they argue for/against the solutions presented. It makes sense that there is disagreement, because it is hard to back up a guess with data. A lot of people are just shooting from the hip. Mix in egos and politics and its amazing it has even gotten this far. I'm rather astounded we have web standards at all (knock on wood).

But I digress. What if you need responsive images in your markup right smurfing now? Because, let's say, theoretically, that there is a crapload of devices loading webpages out there with a huge array of screen sizes and screen densities and screen colors and internet speeds and such. Oh wait.

Even if you're like, screw standards, I just want to do whatever I have to do right now to solve this. These are the options:

  • Skip the src attribute, let JavaScript figure out what the conditions are, inject src. 90% of "new" responsive images solutions I see are this in some flavor1.
  • Get the server involved. Have a cookie (or the like) available with conditions data in it. Intercept the HTTP Request for the img src, check the conditions data, serve up an appropriate image right from the server.

There are existing solutions for both of those techniques, with slightly different ways of going about it. I guide you to those in this article.

And remember a markup-based solution possibly isn't the only place to handle this. There are other ideas floating around that take completely different roads:

  • Perhaps a new image format can help with this inherently.
  • Perhaps servers could help us somehow automatically.
  • Perhaps a new protocol could help.
  • Perhaps we should be able to control browsers prefetching behavior directly.

All the #hotdrama we're having with just the HTML solutions would almost surely happen when we start down those roads.

So yeah, hard.


1 If you're going to make another one of these, I humbly request that you make it like a polyfill and use a syntax that already has some momentum.

Comments

  1. Brian
    Permalink to comment#

    Perhaps a new image format can help with this inherently.

    This, to me at least, would be the ultimate solution. Great article, Chris!

    • Permalink to comment#

      Yes, I think this is true. i think that there is a need for a better solution for responsive images.
      Thanks, chris.

    • Kevin
      Permalink to comment#

      There already is: Webp with perhaps another needing to be in existence to better compress images meant to be animated.

    • Nicklas
      Permalink to comment#

      You mean like storing multiple pictures in one? Kind of like an image-package? That’d be really cool.

    • Robin
      Permalink to comment#

      Use this markup:

      < object data="yourresponsiveimage.svg" ></object>
      

      aaaand in the svg it looks like:

      < svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="yourweight" height="yourheight">
          <defs>
          <style>
          image {display: none;}
          #small {display: block}
           @media screen and (min-width: 401px) and (max-width: 700px) {
              #medium {display: block}
              #small {display: none}
          }
            @media screen and (min-width: 701px) and (max-width: 1000px) {
              #big {display: block}
              #small {display: none}
          }
           @media screen and (min-width: 1001px)  {
            #huge {display: block}
            #small {display: none;}
          }
          </style>
        </defs>
        <g>
          <image id="small"  height="329" width="300" xlink:href="images/small.png" />
          <image id="medium" height="329" width="300" xlink:href="images/medium.png" />
          <image id="big"    height="329" width="300" xlink:href="images/big.png" />
          <image id="huge"   height="329" width="300" xlink:href="images/huge.png" />
        </g>
        </svg>
      

      see the documentation here: https://github.com/estelle/clowncar
      much easier to maintain the images.

  2. It is indeed hard. And like so many things, all we can do is cludge together a solution until, in months or years to come, we have a “proper” way of doing it.

    Sadly I’ve come to the conclusion that when it comes to web development there is no such thing as “perfection” – it’s just a case of making the best with what you have today and hoping a better way of doing things comes about tomorrow.

  3. Permalink to comment#

    I think the main problem is that everybody is trying to solve a problem on the client side which really needs some involvement from the server side to work the way we all want it to.

    • I can’t help feeling that expecting the server to know or care about what screen size someone has is not the right way to go. It’s surely down to the client to determine that, and request content appropriately.

    • Permalink to comment#

      The problem with that is that web developers don’t want to have to put an array of URLs into every IMG tag, it becomes impossible when you introduce a CMS into the mix because my clients aren’t going to upload many copies of their images when creating new blog posts etc.

      The only way forward is either a new type of progressive image format which only delivers the required number of pixels based on the image size/screen ppi, or alternatively “client hints” which tell the server what the maximum size is that an image can be in it’s current placement/media query. The server side script could then deliver an appropriate images based on size and art direction.

    • Chris Ruppel
      Permalink to comment#

      That’s precisely what is being worked on with HTTP Client Hints, which will allow clients to specify what size/type of images they want in a cache-friendly way on servers.

      Combined with a proposal like <picture> or src-n we will have a pretty decent system.

    • To speak directly to the CMS point, if you’re uploading images via an image uploader, why wouldn’t you just tell the CMS to create all the different image sizes you need then use something like the picture element or srcset proposal via polyfill? As an example, WP has plugins that do this already Your text to link here…

    • Permalink to comment#

      Jon,

      Regarding your comment about CMSes and users needing to upload multiple images. I don’t see any reason why if the user was to upload a single (large) image, the CMS couldn’t easily handle creating multiple versions of that image and generating the necessary code to output multiple URLs.

      I think this is the very least of the problem!

    • Permalink to comment#

      The problem with that is that web developers don’t want to have to put an array of URLs into every IMG tag,

      Exactly. Thank you. The problem with a lot of these solutions is all the extra markup. Suddenly a simple project with a lot of images becomes a giant time suck to code and resize 3-4 images per placement. The thing that makes most sense is to let the server handle it. Something in the header of the page (possibly combined with Client Hinting) could tell Apache (or whatever) to create smaller versions of images on the fly to serve to those devices (or bandwidths) that can’t handle the larger one. These alternate size images could (should) be cached on the server as they are created, and batch processing could be automated. It would be future proof too. You wouldn’t have to go back and update legacy html for the next class of devices like say, a Dick Tracy wristwatch browser. You could do it all at once in the init file of the Apache module. And expecting everyone to use a CMS to server and create multiple images is not realistic.

  4. Rasmus Fløe
    Permalink to comment#

    We need a resp. image syntax that can be used as a transition; the end goal would probably be a progressive image format that can be read by the browser (without requirements for the server?) – but untill then we’ll have to start out with shims/polyfills.

    We need to not duplicate rules in markup that we have in CSS (like the viewport part of src-n). A less bloated syntax than srcset. We need a short human-read-/write-able syntax.

    I’ve been thinking long and hard about this – have come up with this: a syntax based on the available image source options (sizes, dpr, format) – srcoptions

  5. Rick H
    Permalink to comment#

    Good timing on this article. I’m working through Aquent’s Responsive Design course online and just finished the images section and it was the most complex part of the whole course. The cleanest method was using background images and the background-sizing style, but that doesn’t seem like the best approach from accessibility standpoint…

    It really makes you wish there was an overarching group that told browser makers what to do.

    • It really makes you wish there was an overarching group that told browser makers what to do.

      When I read the above the first thing I thought was that WE DO..the people, the users, the masses. But then the 2nd thought was that we are still mental infants who have not matured yet into our power to choose wisely. That’s why IE is the most used browser when it is actually the worst.

      So we do not.

      That being said, I think CSS will have to save the day. As said it solves most situations and the rest should be saved by:

      img { max-width: 100%; }

    • Mark Ayers
      Permalink to comment#

      Chrome is the world’s most popluar browser, IE hasn’t been on top since at the most recent January 2013 according to every stats site except Net Applications.

    • @Mark Ayers, statistically speaking that’s true, but you should know better since we all understand that one doesn’t go with what’s most used in the world but with what’s most used by our visitors.

  6. Emmanuel
    Permalink to comment#

    Something akin to image mipmapping from the game development world ought to be implemented. Basic mipmapping generates an image pyramid (large to small) and the graphics card knows what image to swap to depending on view distance. There’s even an image format (DDS) that stores the mipmap pyramid internal to the file (rather than having the game engine generate mipmaps on the fly do it on the fly).

    What that solution would look like for the web, I don’t know.

  7. Permalink to comment#

    Although I agree on solving the problem on the server side as of now, I don’t think that the approach would fly as a standard. I believe the solution should work off a dumb file server (like a directory on your computer), once html, in its basic nature is still a document file, thus the solution should reside on the html document itself.

  8. Zach Ritter
    Permalink to comment#

    Unless I missed it, you missed another issue, CMS. As someone who works in a corporate environment, where you have many content managers whom are not always the most savvy of people, how to manage that becomes a problem. That isn’t to say someone wouldn’t come up with a workable solution after a spec is finalized, but it is to say these content contributors need to be considered.

  9. I’m fed up waiting for an implementation so I decided to use JS as a main solution.

    “Skip the src attribute, let JavaScript figure out what the conditions are, inject src. 90% of “new” responsive images solutions I see are this in some flavor1.”

    I have a better idea for you.

    Instead of skipping the src why don’t we replace the whole <img src="i/normal-img" alt="Some img"/> with <a href="i/normal-img">Some img</a>.

    Then use JS to detect the required image, and replace the <a href> with <img src>.

    If no JS available the <a> still points to the image. So this is semantic/accessible enough for me and falls back nicely on older browsers.

    • Rasmus Fløe
      Permalink to comment#

      That is hilarious! :D

      If people can’t be arsed to choose an autoupdating browser implementing standards that haven’t even been settled upon yet – give them a link to an image – instead of just an inlined image.

  10. It may be hilarious, but it does the job for me. I’ve tried every possible implementation (trick) and so far, they’ve all fell short. So while this may seem like a weird solution, it’s still better/easier than anything I have tested.

    • Rasmus Fløe
      Permalink to comment#

      Oh… you were serious.

      You could also include a noscript tag with an img in it. I mean img-support is pretty good these days – just not the responsive stuff ;)

    • Yes I’ve already added the noscript tag with a default img.

      There are other things you could do to prepare yourself for a markup change when a browser implementation is ready.

      For static images, one can always use media queries with min-device-pixel-ratio (even though the code is ridiculous with browser vendors prefixes; or use LESS) [not my approach]

      The problem is with dynamic images.

      One can create a server side class/function that serves the right markup for images; this way if the a new browser implementation is introduced, all you have to do is change a few lines of code:

      function IMG(imgID){
      
          return '<a href="images[imgID].defaultURL">images[imgID].title</a>';
              //change it to
              //return 'new implementation here';
      
      }
      

      And yes I’m really serious about it.

      After 16+ years, HTML5 is still a candidate recommendation of the W3C (HTML4? 1997!!!).
      So a new image implementation will be available in 2050 (or progressive images…! yes sure. We’ll be on Mars by then).

      Till then, I’ll be using the responsive approach that suits me best based on 3 points:

      1- number of servers request

      2- bandwidth usage (for both mobile devices and servers)

      3- easiest implementation

  11. Perhaps servers could help us somehow automatically.

    I cringe with this one when I think that this already complex dance is now going to include the Server Admin team.

    Web Design + Front End Dev + Programmers + Server Admins = The dance just got even more jacked! o_O

  12. A. H.
    Permalink to comment#

    If you’re not going to have the src attrbute (and only insert it via js), you might as well use background images, no? How is the former more semantic and/or according to the standards?

  13. Rob
    Permalink to comment#

    Why Responsive Images Are So Hard

    I usually end of doing the media queries, but it is sorta ‘jerky’ when the picture jumps around if someone happens to resize their browser.

  14. Permalink to comment#

    You had me at right smurfing now

  15. I will tell you something… without ugly code, now or in the future, we do not have a good standard implementation.

  16. There is need to introduce new library that will dynamically make images as per screen resolution , instead of resizing the images.Because Resizing lost the overall look of images.


    Team TheTechDigit.Com

  17. For responsive image I usually using % in CSS for image resolution.
    for example in this fiddle

    • Nick Coad
      Permalink to comment#

      lol, uh that’s not what this article is about. The code you posted will still download the full-sized image regardless of what size is required.

  18. Permalink to comment#

    Everyone is saying their ways, but there is need of some standard.

  19. Ben Knight
    Permalink to comment#

    Why is it so hard for everyone to agree? Nobody involved is evil. Nobody is is sitting in a dark castle tower laughing maniacally. Nobody is intentionally delaying a solution. At least as far as I know.

    This is a great quote. I imagine this could be said about most disagreements in life.

  20. Very nice thoughts. Maybe a real, unique, solution will never exists. Is worth to experiment a lot anyway!

    I cannot (nowadays) see just one (standard) solution. The needs are so many! Also, I didn’t see yet so many CMSs integrations. I’d like to see something more in the near future about this.

  21. Permalink to comment#

    Yes hopefully they’ll come up with a simpler and more standard way to do responsive images. But for now I’ll have to stick with max-width, media queries, percentages and jQuery options. Thanks much for sharing your thoughts!

  22. Permalink to comment#

    Currently on the web there are tons of articles debating this topic – the possible solutions, the pros and cons…
    Today, responsive images can only be achieved using JavaScript, CSS or server-side detection and are harder to implement and have performance implications compared to regular “img” tags.
    Hope someone will come up with a better solution.

  23. I’m sitting in a dark castle tower laughing maniacally, just for the record.

    • Rasmus Fløe
      Permalink to comment#

      I’m sitting on my stool contemplating what to sow next season while sharpening my pitchfork – for the record ;)

  24. Permalink to comment#

    This issue is another conclusion that the WEB should look more often how Games (-engines) work. I think the best solution for this problem comes very close to the .DDS format, which is a graphic format based on layers which are always divided by x 2. They are called mipmaps (or submaps), imagine a 500x500px document. Underneat the biggest layer there is another layer but only 250x250px image, and underneat there a 125x125px layer, etc.

    For games, a combination of settings like of screen display and graphics card define which layer within this DDS file gets served to give you the best experience, without the need to include (download) the whole file. In gimp the proces of creating the smaller layers goes automatically when saving the image. Texture files within a sprite + mipmaps are extremely effective for games. Imagine looking at a wall from a large distance there is no need to see/download the largest layer but simply a lighter smaller layer, but when you come closer you do want more details so it starts to fade a larger layer. The mechanism for this view distance should be changed for the web based on connection speed and screen ppi.

    Did you know a PNG or JPG file doesn’t becomes bigger in filesize when the format is 2x larger (retina)? Your welcome!

    • You’re right, it doesn’t become larger because it’s already larger. We start with that @2x image size and reduce from there… you know the drill.

      Then the PNG/JPG file in question actually becomes smaller in file size and disk space when you reduce it to standard pixel-size screens.

      The concept of .DDS format is at first glance very interesting because the extra layers are/would be created by the software and not by us so our workflow wouldn’t change since we’d still be exporting a single image/sprite, using a simple <img> tag in the markup with a single src="", and same for background images via CSS.

      However, the only thing that may be a concern is the file size, unless the technology (browsers, OSs, scripts?) somehow ‘discard’ the layers that are not in use and don’t transmit them through the wire, then it’s all good.

      I like that concept… or “technology” better since it already exists.

    • Permalink to comment#

      Yes you get it, instead of a game engine we need some help from the browser to tell the server(-software) which layer to use based on values like image dimentions defined in the html/css + screen ppi.

      Another thing i just want to specificly point out (because we seem so worried about presenting the user perfecr pixels) is:

      We have a original jpg of 800×800, we need it on 200×200 at quality 90% to keep it pretty, this resized image is bigger in filesize when we make a 400×400 jpg at 60% quality and looks even sharper, especially on retina displays. So why even bother caring the 200×200 version if our retina ready image looks better and is smaller in filesize?

    • Permalink to comment#

      To answer myself on the last part about why even bother about normal screens if a retina ready image looks better and is smaller in file size compared to 50% smaller image with a much higher compression is because the browser creates an FPS/lag for re-rendering the too big image into a smaller image placeholder. The bigger the retina image the bigger the lag, at least that has been researched in Chrome and ie11, check out this article which ends with some very good questions:

      How do (other) browsers handle image decoding and resizing?
      How do these results change as file weight is adjusted up or down (important for compressive images, for example)?
      Does file format impact decoding and resizing times?

      http://timkadlec.com/2013/11/why-we-need-responsive-images-part-deux/

  25. Matthew Trow
    Permalink to comment#

    When it comes to images in the markup, my solution WAS to just serve up one image that’s of a reasonable resolution and filesize with an option to click to view a larger image.
    I’m really not going to sweat it, if a mobile device only capable of 320×240 resolution has to download an 800×600 jpg that’s 60kb.

    I’m also not too worried if my 800×600 scales up to 1024×768 – again, I’ll provide a link to a hi-res version if the quality of the image is of huge importance.

    If my website is serving up 10, 15, 20 large images on a single page, clearly I’m doing something terribly wrong, or I’m going into competition with Flickr.

    I say this was my preferred solution, as now retina devices have come along and made things so much harder.

    My solution now is to hide under my desk and gibber like a crazed chimp on a sugar high.

  26. Permalink to comment#

    May anybody try to bootstrap and just use class “hidden xs” “vissible lg”. Am I right?

  27. Matt
    Permalink to comment#

    Shouldn’t the title of the post be “Why Responsive Images ARE so hard?”

    • Phoenic Steel
      Permalink to comment#

      I believe “responsive images” is the subject, as in we are not talking about the images themselves but about responsive imagery.

      The reason we use “is” is because “responsive images” becomes a plural subject, it is the name of the thing we are talking about, it is one theme and therefore it becomes singular.

  28. Md Kamruzzaman Sumon
    Permalink to comment#

    You Can use for Responsive background image easily:-

    banner-panel{

    background: url(images/banner.jpg) no-repeat;
    background-size:100% auto;
    padding: 0px;
    max-width: 1500px;
    min-height: 395px;
    

    }

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".