#133: Figuring Out Responsive Images

I'm probably a bit rare in that I rather enjoyed trying to keep up on the responsive images thing. It's an interesting problem that bred lots of interesting solutions. The whole thing is starting to wrap up now though, now that the official solutions are:

  1. <picture> and friends
  2. <img> with srcset and sizes

The problem is: I don't really get it. I thought the original picturefill was pretty simple. List a bunch of sources with media queries. First one to match, that's the one that gets used. That made sense to me. This new stuff is a bit different. Solvable problem! Just like everything else, I need to figure it out.

That's why I was totally sympathetic to Martin Wolf's post "The new srcset and sizes explained" where he was struggling with the same problem. So I used that as a starting point for playing myself.

Here's some things I've learned.

This part makes sense I think:

And this is where it gets weird:

Why are we telling the browser how big an image is? It's a browser. Shouldn't it know how big images are? Well it does, but only after it downloads the entire thing. Smarter decisions can be made right off the bat if it knows this information sooner. So we just tell it. You could lie. Or be wrong. Which is weird but whatever.

Now that you have those different image options listed, you'll need to also use the sizes attribute. This provides more information to the browser about what how to intend to display the image so it can use that in making a choice about which.

The sizes attribute is also weird to me:

Again, it's all about intention. The sizes attribute doesn't actually have any effect on the size the image actually renders. (I was wrong about that in the video.) That's left to the real actual image size itself, or (more likely) CSS. We're just giving the browser information about what we intend to do so that it can make a smart choice about which image to use. I think it feels weird because we could again, lie, or be wrong, which is unusual thing in HTML.

If we provide all this info, and do it right, then the browser (or the polyfill) can make a smart choice about what image to display.

Let's take this example:

  srcset="large.png 1280w,
          medium.png 640w,
          small.png 320w"

Say we're on a 1x screen. Because we've told the browser we're going to be using these images as big as we possibly can (100% of the viewport), the "breakpoints" for when the browser will flip out the images will happen at 1280px, 640px, and 320px, the same exact sizes as we've told it the images are.

If we're on a 2x screen, those "breakpoints" will cut in half (regardless of what we actually do to size those images) and will be at 640px, 320px, and 160px.

Now let's say we use the same images, but we know a lot more about our page layout, and used something like this:

  srcset="large.png 1280w,
          medium.png 640w,
          small.png 320w"
     sizes="(max-width: 500px) 250px, 500px"  

Here we're saying (with the sizes attribute), if the viewport is 500px or smaller, we intend to display the image at 250px wide. If the viewport is wider than that, display the image at 500px wide.

That would match up with CSS like this:

img {
  width: 500px;
@media (max-width: 500px) {
  img {
    width: 250px;

On a 1x screen, you'll always get the 320w (small) image when the viewport is 500px wide or smaller, and you'll always get the 640w (medium) image when the viewport is larger. You'll never get the large image, because it can tell you'll never need that many pixels.

Ona 2x screen, you'll always get the 640w (medium) image when the viewport is 500px wide or smaller (because it thinks it needs 500px of pixels and the small isn't enough at 320px), and you'll always get the 1280w (large) image when the viewport is larger. You'll never get the small image, because it's never enough pixels to cover what you've told it you intend to render the image at.

Actual Sizing

Remember the actual sizing of the image is still up to you. I would think in the majority of cases it's you doing it through the CSS. And the CSS always wins. What you declare there will be the rendered width of the image no matter what happens with the srcset and sizes stuff. That just works out which image will be shown.

This is what makes the sizes attribute a bit tough. Let's say you have something like:

.container {
  width: 80%;
.container article {
  width: 50%;
.container article img {
  width: 33.33%

That's not unusual at all. So now what size do you use in the sizes attribute? That would be 13.33% (multiply them all together) because that number needs to be relative to the viewport, not the container. And that doesn't take into account margins and padding and stuff on those containers, so it's kind of a guess. I guess close counts in horseshoes, hand grenades, and the sizes attribute.

Then let's say a media query comes along and the body actually becomes 75% wide on top of all that. You need to know that so you can adjust what you think the rendered size of the images will be. Your sizes attribute might become:

sizes="(min-width: 500px) 8%, 13.33%"

Then go through that again for every layout media query you have that affects content images. It can get a bit complex.

Practical Sizes?

I suspect most real world usage will use something like:

  srcset="large.png 1280w,
          medium.png 640w,
          small.png 320w"
     sizes="(min-width: 500px) 50%, 100%"  

Assuming that content images will be around half the size of the browser window on large screens and the full size of the browser window on small screens - just let the breakpoints happen where they happen. You'll still get a pretty decent choice this way without slaving away over matching all your media queries exactly.

And remember these are content images. HTML tends to last longer than CSS or JS does, especially when it's content.

Other Things To Know

You can also specify if an image is 2x or 1x with srcset. So a really simple use case can be:

<img srcset="small.jpg 1x, large.jpg 2x"
   alt="whatever" />

That alone is pretty useful. Don't mix it with specifying widths. As Eric Portis says:

And again let me emphasize that while you can attach 1x/2x resolution descriptors to sources in srcset instead of w descriptors, 1x/2x & w do not mix. Don’t use both in the same srcset. Really.

And remember when I said the original picturefill was easy? The new <picture> can be that easy, but the <source> elements inside <picture> also support srcset and sizes. That means you can get very specific. It adds another layer to this:

  1. You decide which gets displayed based on media queries
  2. That has it's own srcset/sizes, for determining exactly which src gets used

Here's an example from Eric Portis' recent Smashing Magazine article:

   <source media="(min-width: 36em)"
      srcset="large.jpg  1024w,
         medium.jpg 640w,
         small.jpg  320w"
      sizes="33.3vw" />
   <source srcset="cropped-large.jpg 2x,
         cropped-small.jpg 1x" />
   <img src="small.jpg" alt="A rad wolf" />


See the Pen srcset & sizes testcase by Chris Coyier (@chriscoyier) on CodePen.


  1. User Avatar
    Alex Howes

    This is some great progress with the spec finally being implemented.
    I guess I’m kind of more curious in how CMS’s will allow for it to be utilised and as to whether clients will grasp the idea.
    Least i know that I can start using this stuff on my recent projects with the polyfill.

    • User Avatar

      I managed to get this working in WP for 3 different sized header images for large, medium and small viewports.

      Just add three image sizes to your functions.php like so:

          add_image_size('lrg-hdr', 1170, 544, true); 
      add_image_size('med-hdr', 750, 400, true); 
      add_image_size('sml-hdr', 500, 325, true); 

      and then for the template drop this in:

      srcset=" 1170w,

      Thanks for another great tutorial.

  2. User Avatar

    Hadn’t heard about srcset until now but it looks great. Plus, I can take still use this on client projects by letting the CMS take control of creating/ loading multiple versions of their image. Awesome!

  3. User Avatar

    Nice as always..Chris!

  4. User Avatar
    Šime Vidas

    We’re going to need a cookbook for this stuff haha

  5. User Avatar
    Justin Avery

    Great overview Chris (following on from Erics’ overview on his own site and Smashing recently).

    I can feel new brain synapses developing with each pass over these articles and each new codepen. Hoping to have a list of patterns for this as part of going over it time and time again, if you’re working on something similar give me a shout and I’ll send my stuff through.

  6. User Avatar
    Erik Isaksen

    Thanks for all of your hard work in the community. Great Work!

  7. User Avatar
    Fred Campbell

    Hi Chris, what happened to your Rode Podcaster mic, sounds like you’re sitting in an oil barrel!

    • User Avatar
      Chris Coyier

      Yeah trying out some new stuff (blue yeti mic thingy) – gotta fix that.

  8. User Avatar
    Ian Mustafa

    The third code block should be like this:

    img {
      width: 500px;
    @media (max-width: 500px) {
      img {
        width: 250px;

    You missed the img selector in @media

    • User Avatar
      Chris Coyier

      Good catch! Dumb me. I probably had it nested but then moved it out because that’s a weird thing to chuck in there in an article like this so moved it out and forgot how that works derp.

  9. User Avatar

    Is this method only compatible with newer browsers? There doesn’t seem to be any mention of compatibility, is it safe to assume this works with all browsers then?

    • User Avatar

      The <picture> element and the srcset attributes are currently not supported by any browsers without the help of a polyfill. The Picturefill polyfill included in the list of links at the end will enable both features in most browsers. The Picturefill website has more detailed documentation about browser support.

      Now that the spec is being nailed down, it is likely that the major browsers will begin supporting it natively in the near future.

    • User Avatar
      Permalink to comment#

      No. It’s not. And if you’re interested in front end development this site should be your bible: http://caniuse.com/#search=srcset.

  10. User Avatar

    I will use this in my current responsive website project.

    Tested this on windows IE7, IE8, IE9 and works just fine.

    I need to see how it will work on with a responsive Slider

  11. User Avatar
    Samuel Larsson

    Great walkthrough! Only on question left: If we provide the browser with detailed “sizes”-info (max/min-widths + relative widths)—would there be no or little use for “2x” in srcset? Does this solution handle resolution when picking images, even without the 2x-thing?

    • User Avatar
      Chris Coyier

      The most important advice is use EITHER the w values OR the x values, never both.


      srcset="image.jpg 1280w"
      srcset="image.jpg 2x"


      srcset="image.jpg 1280w 2x"
  12. User Avatar

    It’s good to see the final solution includes a backward compatible img implementation, the picture element was always going to be an issue with legacy browsers.

  13. User Avatar
    Permalink to comment#

    As Mr Burns would say “Excellent”.

  14. User Avatar
    Permalink to comment#

    Its excellent solution, instead of using the img{width:100%;} in CSS

  15. User Avatar
    Permalink to comment#

    Not particularly current nor maybe even relevant to this thread, but I’ve been using the code below for a few years and get the desired results ( in this case responsive bg images)
    In the WP header file

    $(document).ready(function() {
        bgImageTotal = 11;
        var randomNumber = Math.round(Math.random()*(bgImageTotal-1))+1;
            'background' : 'url("'+imgPath+'") 100% 0 no-repeat',
            'background-size' : '100%'

    The key rules in the #wrapper ID in style.css

        position: relative;
        width: 100%; height: 100%;
        max-width: 1280px; max-height: 800px; 
        margin: 1% auto; padding: 1% 0;

    This seems to get it right and because I’m using jQuery IE8 even plays nice (with, to be fair, the default use of css3-mediaqueries.js)

    That being said, I’m sure I could learn a thing or two from taking a look at these new standards.

  16. User Avatar

    Maybe a stupid question but I am little bit confused. So in the future I can use BOTH responsive image solutions?

    picture and friends
    img with srcset and sizes

    At the moment “picture” seems more logical to me but I think like Martin Wolf I need some time get it.

  17. User Avatar
    trCreative Web Design Cheshire

    Nice technique using srcset, a new one to me, thanks.

  18. User Avatar
    Tomas Kapler
    Permalink to comment#

    I want to use it on eshop with one simply rule – display low-res images on mobile phones and better quality ones on desktop. I asume that with doing this, i could save quite a lot of data trafic for mobile users so as a sideeffect increase for them the speed of the web. I know that mobile phones now got sometimes very high resolution, so i would like to target lowress displays the low resolution displays or higher with some multiplier. And i would like to do it with shortest possible html code with only 2 img versions (btw i heard that e.g. jpg with compression lvl 60 resized to 50 % is nicer and data-smaller, then nonresized quality 90 jpg) and with good enough compatibility (most used android, ios, winphone mobile browsers). What code would you reccomend?

  19. User Avatar
    Permalink to comment#

    Great stuff as usual!

    I noticed that if you add the src fallback, both the fallback image and the intended image are both loaded by the browser.

    Also, the img srcset option does not seem to work in mobile Safari on my iPhone 5. I’m still seeing the extralarge.jpg in this Picturefill demo: http://scottjehl.github.io/picturefill/examples/demo-01.html

  20. User Avatar
    Permalink to comment#

    Please, check out my idea how to always show better image for client, according to it`s screen resolution and image aspect ratio: http://jsfiddle.net/iegik/cA7SV/

  21. User Avatar
    Permalink to comment#

    Great article, RWD is feeling complete. Speaking of WP, I wrote a function to use in the theme templates when calling the post_thumbnail:

    function responsive_featured_img() {
        global $post;
        if ( function_exists('has_post_thumbnail') && has_post_thumbnail($post->ID) ) {
            $feat_small = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'small' );
            $feat_med = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'medium' );
            $feat_large = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'large' ); ?>
    <img src="<?php echo $feat_small[0]; ?>"
        srcset="<?php echo $feat_large[0]; ?> 1024w, <?php echo $feat_med[0]; ?> 400w, <?php echo $feat_small[0]; ?> 320w"
        alt="<?php echo get_the_title($post->ID); ?>" /> 
    <?php } } ?>
  22. User Avatar
    Permalink to comment#

    Great article. I’ve just started implementing Picturefill in WordPress and have been using this function on feature images:

    function the_responsive_thumbnail($post_id) {
        // Check to see if there is a transient available. If there is, use it.
        if ( false === ( $thumb_data = get_transient( 'featured_image_' . $post_id ) ) ) {
            $thumb_data = get_transient( 'featured_image_' . $post_id );
        echo '';
        echo '<!--[if IE 9]><![endif]-->';
        echo '';
        echo '';
        echo '';
        echo '<!--[if IE 9]><![endif]-->';
        echo '';
        echo '';

    Any ideas on how to modify this to remove the picture element and only include srcset?

  23. User Avatar
    Permalink to comment#


  24. User Avatar
    Permalink to comment#

    I am confused.com (have to read again … and again)
    It all looks like a load more ruddy work (trail / error / trial) to me … and trying to explain that to clients ?!!?!?!
    I am old school, brought-up on penny-pinching bandwidth and 48K Dial-ups … every pixel, character and byte was squeezed out of HTML/CSS/Script … now it’s BLOATSVILLE !! Especially ruddy WordPress which already hogs TB of used server space/ creates unused images litke there is no tomorrow and 1000’s of php files to serve a few ruddy pages!

    I quit !!__ (rant rant rant !!)

    Great article actually .. thank you for sharing.

  25. User Avatar
    Permalink to comment#

    I’m just wondering, If I want to use srcset I must have picture with different size as example :
    I want to use srcset for my image named ‘pic.jpg’ it had 1280×1024 px, If I want to use it for I pad, I must re-size it ( to Ipad dimension) and save it ‘ipad.jpg’ and so on for all screens ?? Or just one picture and the srcset will do the other?? Because to me is better to use one picture in my ‘Media folder’ and give it a style in Css file to re-size it based on screen device than use 3 or 4 pictures and give it a style in my Css file

  26. User Avatar
    Permalink to comment#

    This article is great, but in my humble opinion i think you should educate your readers about browsers that don’t support the srcset attribute. People shouldn’t only know how to use this technology but also how they would write a fallback for older browsers which achieves the exact same effect.

    For people who are interested in which browsers support the srcset attribute: http://caniuse.com/#search=srcset.

  27. User Avatar
    Permalink to comment#

    This is pretty cool stuff! Seems simple, elegant and quite frankly very useful. I haven’t had time to play around w/ it yet but it’s on my to do list. I am curious if there have been any issues on mobile platforms or if that too is seem-less and supported???


  28. User Avatar
    Marty Powell
    Permalink to comment#

    Is anyone able to pen included at the bottom working in chrome 41? CanIUse(http://caniuse.com/#feat=srcset) suggests this is supported but the images are not swapping out.

    Pen: http://codepen.io/chriscoyier/pen/reFLJ

    • User Avatar
      Permalink to comment#

      I’m experiencing the same thing. Any input Chris?

    • User Avatar
      Permalink to comment#

      The picturefill demo doesn’t seem to be working either for me. All I see is extralarge.jpg


    • User Avatar
      Chris Coyier
      Permalink to comment#

      Hey ya’ll –

      Are you trying to resize the area smaller and expecting to see the larger image get swapped out by the smaller one?

      If so, that’s not how it works anymore. Spec change I think, and Picturefill updated to match. If the browser already has the larger image it won’t swap it out for a smaller one (because why would it, it’s more efficient not to).

    • User Avatar

      Almost forgot about this comment. Ah, ok. Didn’t realise that. That is a much smarter implementation though, as you state. Thanks Chris.

  29. User Avatar
    Permalink to comment#

    yeah, images are not swapping correctly, i tried to resize, its not working, im using chrome and firefox.

  30. User Avatar
    Permalink to comment#

    In your “Practical Sizes?” section the code for sizes is

    sizes="(min-width: 500px) 50%, 100%"

    and you state

    Assuming that content images will be around half the size of the browser window on small screens and the full size of the browser window on large screens

    I think you meant to say

    Assuming that content images will be around half the size of the browser window on large screens and the full size of the browser window on small screens

  31. User Avatar
    Permalink to comment#

    I’ve often had to use background image options in order to manage images, and generally the images that pose the biggest problems are photos that are full page photos that have to be laid out in different orientations, and it mobile and have a focal point in the photo (such as a person’s face). Getting the photo to line up consistently and scale is really impossible. Which then requires 3 to 12 different size images. This is why most people use a generic photo in the background with a single button in the middle. Because it doesn’t matter how the photo is laid out.

  32. User Avatar
    Permalink to comment#


    Regarding bandwidth –

    Does this load only the image that the browser choozeez??

    Or all zee imagez in the srcset?

  33. User Avatar
    Kerry Kobashi
    Permalink to comment#


    According to WHATWG, percentages are no longer allowed. Section 4.8.4 says:

    “Percentages are not allowed in a , to avoid confusion about what it would be relative to.”

  34. User Avatar
    Permalink to comment#

    Hi Chirs,

    I have one question, Loading retina images for user having slower mobile connection will slow down the site.

    How can we prevent loading retina images for mobile devices and load standard image?


Leave a Comment

Posting Code!

You may write comments in Markdown. This makes code easy to post, as you can write inline code like `<div>this</div>` or multiline blocks of code in triple backtick fences (```) with double new lines before and after.

Code of Conduct

Absolutely anyone is welcome to submit a comment here. But not all comments will be posted. Think of it like writing a letter to the editor. All submitted comments will be read, but not all published. Published comments will be on-topic, helpful, and further the discussion or debate.

Want to tell us something privately?

Feel free to use our contact form. That's a great place to let us know about typos or anything off-topic.