Responsive Images Done Right: A Guide To <picture> And srcset

Advertisement

On Monday, we published an article on Picturefill 2.01, a perfect polyfill for responsive images. Today’s article complements Tim Wright’s article and explains exactly how we can use the upcoming <picture> element and srcset, with simple fallbacks for legacy browsers. There is no reason to wait for responsive images2; we can actually have them very, very soon3. — Ed.

“Everything I’ve said so far could be summarized as: make pages which are adaptable.… Designing adaptable pages is designing accessible pages. And perhaps the great promise of the web, far from fulfilled as yet, is accessibility, regardless of difficulties, to information.”

– John Allsopp, A Dao of Web Design4

Images5 are some6 of the most7 important8 pieces9 of information10 on the web11, but over the web’s 25-year history, they haven’t been very adaptable at all. Everything about them has been stubbornly fixed: their size, format and crop, all set in stone by a single src.

HTML authors began to really feel these limitations when high-resolution screens and responsive layouts hit the web like a one-two punch. Authors — wanting their images to look crisp in huge layouts and on high-resolution screens — began sending larger and larger sources to everyone; the average size of an image file ballooned12; very smart people called responsive web design "unworkably slow13".

Images have been the number one obstacle to implementing truly adaptable and performant responsive pages — pages that scale both up and down, efficiently tailoring themselves to both the constraints and the affordances of the browsing context at hand.

That is about to change.

The latest specification of the <picture> element14 is the result of years15 (years!16) of debate on how to make images adapt. It gives authors semantic ways to group multiple versions of the same image, each version having technical characteristics that make it more or less suitable for a particular user. The new specification has achieved broad consensus and is being implemented in Chrome, Opera and Firefox (maybe even Internet Explorer!17) as I type.

The time to start learning this stuff is now!

Before we get to any of the (shiny! new!) markup, let’s look at the relevant ways in which browsing environments vary, i.e. the ways in which we want our images to adapt.

  1. Our images need to be able to render crisply at different device-pixel-ratios. We want high-resolution screens to get high-resolution images, but we don’t want to send those images to users who wouldn’t see all of those extra pixels. Let’s call this the device-pixel-ratio use case.
  2. If our layout is fluid (i.e. responsive), then our images will need to squish and stretch to fit it. We’ll call this fluid-image use case.
  3. Note that these two use cases are closely related: To solve both, we’ll want our images to be available in multiple resolutions so that they scale efficiently. We’ll call tackling both problems simultaneously the variable-sized-image use case
  4. Sometimes we’ll want to adapt our images in ways that go beyond simple scaling. We might want to crop the images or even subtly alter their content. We’ll call this the art-direction use case.
  5. Finally, different browsers support different image formats. We might want to send a fancy new format such as WebP to browsers that can render it, and fall back to trusty old JPEGs in browsers that don’t. We’ll call this the type-switching use case.

The new <picture> specification includes features for all of these cases. Let’s look at them one by one.


Rearranging images across various resolutions is relatively easy, however, loading different images (and only them) depending on the user’s resolution is quite difficult. Well, not any more. (Image credit18)

The device-pixel-ratio Use Case

Let’s start simply, with a fixed-width image that we want to adapt to varying device-pixel-ratios. To do this, we’ll use the first tool that the new specification gives us for grouping and describing image sources: the srcset attribute.

Say we have two versions of an image:

  • small.jpg (320 × 240 pixels)
  • large.jpg (640 × 480 pixels)

We want to send large.jpg only to users with high-resolution screens. Using srcset, we’d mark up our image like so:

<img srcset="small.jpg 1x, large.jpg 2x"
   src="small.jpg"
   alt="A rad wolf" />

The srcset attribute takes a comma-separated list of image URLs, each with an x descriptor stating the device-pixel-ratio that that file is intended for.

The src is there for browsers that don’t understand srcset. The alt, of course, is included for browsers that don’t render images at all. One element and three attributes gets us an image that looks crisp on high-resolution devices and efficiently degrades all the way down to text. Not too shabby!

The Fluid- And Variable-Sized-Image Use Cases

What that markup won’t do is efficiently squish and stretch our image in a fluid layout. Before addressing this fluid-image use case, we need a little background on how browsers work.

Image preloading is, according to Steve Souders, “the single biggest performance improvement browsers have ever made19.” Images are often the heaviest elements on a page; loading them ASAP is in everyone’s best interest. Thus, the first thing a browser will do with a page is scan the HTML for image URLs and begin loading them. The browser does this long before it has constructed a DOM, loaded external CSS or painted a layout. Solving the fluid-image use case is tricky, then; we need the browser to pick a source before it knows the image’s rendered size.

What a browser does know at all times is the environment it’s rendering in: the size of the viewport, the resolution of the user’s screen, that sort of thing. We use this information when we use media queries, which tailor our layouts to fit particular browsing environments.

Thus, to get around the preloading problem, the first proposals20 for fluid-image features21 suggested attaching media queries to sources. We would base our source-picking mechanism on the size of the viewport, which the browser knows at picking-time, not on the final rendered size of the image, which it doesn’t.

22
Dealing with responsive images turned out to be quite a nightmare. A better way to provide the browser with details about its environment is by simply telling the browser the rendered size of the image. Kind of obvious, really. (Image credit23)

As it turns out24, that’s a bad idea. While it’s technically workable, calculating the media queries needed is tedious and error-prone. A better idea is to simply tell the browser the rendered size of the image!

Once we tell the browser how many pixels it needs (via a new attribute, sizes) and how many pixels each of the sources has (via w descriptors in srcset), picking a source becomes trivial. The browser picks the smallest source that will still look reasonably crisp within its container.

Let’s make this concrete by developing our previous example. Suppose we now have three versions of our image:

  • large.jpg (1024 × 768 pixels)
  • medium.jpg (640 × 480 pixels)
  • small.jpg (320 × 240 pixels)

And we want to place these in a flexible grid — a grid that starts out as a single column but switches to three columns in larger viewports, like this25:

26
A responsive grid example. (See the demo27)

Here’s how we’d mark it up:

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

We’re using srcset again, but instead of x descriptors, we’re attaching w descriptors to our sources. These describe the actual width, in pixels, of the referenced file. So, if you “Save for Web…” at 1024 × 768 pixels, then mark up that source in srcset as 1024w.

You’ll note that we’re specifying only image widths. Why not heights, too? The images in our layout are width-constrained; their widths are set explicitly by the CSS, but their heights are not. The vast majority of responsive images in the wild are width-constrained, too, so the specification keeps things simple by dealing only in widths. There are some good28 reasons29 for including heights, too — but not yet.

So, that’s w in srcset, which describes how many pixels each of our sources has. Next up, the sizes attribute. The sizes attribute tells the browser how many pixels it needs by describing the final rendered width of our image. Think of sizes as a way to give the browser a bit of information about the page’s layout a little ahead of time, so that it can pick a source before it has parsed or rendered any of the page’s CSS.

We do this by passing the browser a CSS length30 that describes the image’s rendered width. CSS lengths can be either absolute (for example, 99px or 16em) or relative to the viewport31 (33.3vw, as in our example). That “relative to the viewport” part is what enables images to flex.

If our image occupies a third of the viewport, then our sizes attribute should look like this:

sizes="33.3vw"

Our example isn’t quite so simple. Our layout has a breakpoint at 36 ems. When the viewport is narrower than 36 ems, the layout changes. Below that breakpoint, the image will fill 100% of the viewport’s width. How do we encode that information in our sizes attribute?

We do it by pairing media queries with lengths:

sizes="(min-width: 36em) 33.3vw,
   100vw"

This is its format:

sizes="[media query] [length],
   [media query] [length],
   etc…
   [default length]"

The browser goes over each media query until it finds one that matches and then uses the matching query’s paired length. If no media queries match, then the browser uses the “default” length, i.e. any length it comes across that doesn’t have a paired query.

With both a sizes length and a set of sources with w descriptors in srcset to choose from, the browser has everything it needs to efficiently load an image in a fluid, responsive layout.

Wonderfully, sizes and w in srcset also give the browser enough information to adapt the image to varying device-pixel-ratios. Converting the CSS length, we give it in sizes to CSS pixels; and, multiplying that by the user’s device-pixel-ratio, the browser knows the number of device pixels it needs to fill — no matter what the user’s device-pixel-ratio is.

So, while the example in our device-pixel-ratio use case works only for fixed-width images and covers only 1x and 2x screens, this srcset and sizes example not only covers the fluid-image use case, but also adapts to arbitrary screen densities.

We’ve solved both problems at once. In the parlance set out at the beginning of this article, w in srcset and sizes covers the variable-sized-image use case.

Even more wonderfully, this markup also gives the browser some wiggle room. Attaching specific browsing conditions to sources means that the browser does its picking based on a strict set of conditions. “If the screen is high-resolution,” we say to the browser, “then you must use this source.” By simply describing the resources’ dimensions with w in srcset and the area they’ll be occupying with sizes, we enable the browser to apply its wealth of additional knowledge about a given user’s environment to the source-picking problem. The specification allows browsers to, say, optionally load smaller sources when bandwidth is slow or expensive.

One more thing. In our example, the size of the image is always a simple percentage of the viewport’s width. What if our layout combined both absolute and relative lengths by, say, adding a fixed 12-em sidebar to the three-column layout, like this32?

33
A layout combines absolute and relative lengths. (See the demo34)

We’d use the surprisingly well-supported35 calc() function36 in our sizes attribute.

sizes="(min-width: 36em) calc(.333 * (100vw - 12em)),
   100vw"

And… done!

The Art-Direction Use Case

Now we’re cooking with gas! We’ve learned how to mark up varible-sized images that scale up and down efficiently, rendering crisply on any and all layouts, viewports and screens.

But what if we wanted to go further? What if we wanted to adapt more?

When Apple introduced the iPad Air last year, its website featured a huge image of the device37. This might sound rather unremarkable, unless you — as web design geeks are wont to do — compulsively resized your browser window. When the viewport was short enough, the iPad did a remarkable thing: it rotated to better fit the viewport38!

We call this sort of thing “art direction.”

Apple art-directed its image by abusing HTML and CSS: marking up its image — which was clearly content — as an empty div and switching its background-image with CSS. The new <picture> specification allows authors to do this sort of breakpoint-based art direction entirely in HTML.

The specification facilitates this by layering another method of source grouping on top of srcset: <picture> and source.

Let’s get back to our example. Suppose that instead of letting our image fill the full width of the viewport on small screens, we crop the image square, zooming in on the most important part of the subject, and present that small square crop at a fixed size floated off to the left, leaving a lot of space for descriptive text, like this39:

40
An example with images combined with descriptive text. (See the demo41)

To achieve this, we’ll need a couple of additional image sources:

  • cropped-small.jpg (96 × 96 pixels)
  • cropped-large.jpg (192 × 192 pixels)
  • small.jpg (320 × 240 pixels)
  • medium.jpg (640 × 480 pixels)
  • large.jpg (1024 × 768 pixels)

How do we mark them up? Like so:

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

This example is as complex as it gets, using every feature that we’ve covered so far. Let’s break it down.

The <picture> element contains two sources and an img. The sources represent the two separate art-directed versions of the image (the square crop and the full crop). The (required) img serves as our fallback. As we’ll soon discover, it does much of the actual work behind the scenes.

First, let’s take a close look at that first source:

<source media="(min-width: 36em)"
   srcset="large.jpg  1024w,
      medium.jpg 640w,
      small.jpg  320w"
   sizes="33.3vw" />

This source represents the full uncropped version of our image. We want to show the full image only in the three-column layout — that is, when the viewport is wider than 36 ems. The first attribute here, media="(min-width: 36em)", makes that happen. If a query in a media attribute evaluates to true, then the browser must use that source; otherwise, it’s skipped.

The source’s other two attributes — srcset and sizes — are mostly copied from our previous variable-sized-image example. One difference: Because this source will be chosen only for the three-column layout, our sizes attribute only needs a single length, 33.3vw.

When the viewport is narrower than 36 ems, the first source’s media query will evaluate to false, and we’d proceed to the second:

<source srcset="square-large.jpg 2x,
                square-small.jpg 1x" />

This represents our small square crop. This version is displayed at a fixed width, but we still want it to render crisply on high-resolution screens. Thus, we’ve supplied both 1x and 2x versions and marked them up with simple x descriptors.

Lastly, we come to the surprisingly important (indeed, required!) img.

Any child of an audio or video element that isn’t a source is treated as fallback content and hidden in supporting browsers. You might, therefore, assume the same thing about the img here. Wrong! Users actually see the img element when we use <picture>. Without img, there’s no image; <picture> and all of its sources are just there to feed it a source.

Why? One of the main complaints about the first <picture> specification was that it reinvented the wheel, propsing an entirely new HTML media element, along the lines of audio and video, that mostly duplicated the functionality of img. Duplicated functionality means duplicated implementation and maintenance work — work that browser vendors weren’t keen to undertake.

Thus, the new specification’s reuse of img. The <picture> itself is invisible, a bit like a magical span. Its sources are just there for the browser to draw alternate versions of the image from. Once a source URL is chosen, that URL is fed to the img. Practically speaking, this means that any styles that you want to apply to your rendered image (like, say, max-width: 100%) need to be applied to img, not to <picture>.

OK, on to our last feature.

The Type-Switching Use Case

Let’s say that, instead of doing all of this squishing, stretching and adapting to myriad viewport conditions, we simply want to give a new file format a spin and provide a fallback for non-supporting browsers. For this, we follow the pattern established by audio and video: source type.

<picture>
   <source type="image/svg" src="logo.svg" />
   <source type="image/png" src="logo.png" />
   <img src="logo.gif" alt="RadWolf, Inc." />
</picture>

If the browser doesn’t understand the image/svg media type42, then it skips the first source; if it can’t make heads or tails of image/png, then it falls back to img and the GIF.

During the extremely painful GIF-to-PNG transition43 period, web designers would have killed for such a feature. The <picture> element gives it to us, setting the stage for new image formats to be easily adopted in the years to come.

That’s It!

That’s everything: every feature in the new <picture> specification and the rationale behind each. All in all, srcset, x, w, sizes, <picture>, source, media and type give us a rich set of tools with which to make images truly adaptable — images that can (finally!) flow efficiently in flexible layouts and a wide range of devices.

The specification is not yet final. The first implementations are in progress and are being staged behind experimental flags; its implementors and authors are working together to hash out the specification’s finer details on a daily basis. All of this is happening under the umbrella of the Responsive Images Community Group44. If you’re interested in following along, join45 the group, drop in on the IRC channel46, weigh in on a GitHub issue47 or file a new one, sign up for the newsletter48, or follow the RICG on Twitter49.

(il, al)

Footnotes

  1. 1 http://www.smashingmagazine.com/2014/05/12/picturefill-2-0-responsive-images-and-the-perfect-polyfill/
  2. 2 http://timkadlec.com/2014/05/dont-wait-on-responsive-images/
  3. 3 https://twitter.com/wilto/status/465850875102371840
  4. 4 http://alistapart.com/article/dao
  5. 5 http://www.google.com/imghp
  6. 6 http://mashable.com/2013/09/16/facebook-photo-uploads/
  7. 7 http://www.loc.gov/pictures/
  8. 8 https://www.flickr.com/commons
  9. 9 http://www.google.com/culturalinstitute/about/artproject/
  10. 10 http://www.huffingtonpost.com/2012/07/10/first-photo-ever-on-the-internet-les-horribles-cernettes_n_1662823.html
  11. 11 http://bukk.it/look.jpg
  12. 12 http://httparchive.org/trends.php?s=All&minlabel=Nov+15+2010&maxlabel=Apr+1+2014#bytesImg&reqImg
  13. 13 http://blog.cloudfour.com/css-media-query-for-mobile-is-fools-gold/
  14. 14 http://picture.responsiveimages.org
  15. 15 http://www.brucelawson.co.uk/2011/notes-on-adaptive-images-yet-again/
  16. 16 http://lists.w3.org/Archives/Public/public-html/2007Jul/0121.html
  17. 17 http://status.modern.ie/pictureelement
  18. 18 http://picture.responsiveimages.org/images/viewport_selection_mob_first.jpg
  19. 19 http://www.stevesouders.com/blog/2013/04/26/i/
  20. 20 http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2012-May/035855.html
  21. 21 http://alistapart.com/article/responsive-images-how-they-almost-worked-and-what-we-need
  22. 22 http://ericportis.com/posts/2014/srcset-sizes/
  23. 23 http://ericportis.com/posts/2014/srcset-sizes/
  24. 24 http://ericportis.com/posts/2014/srcset-sizes/
  25. 25 http://ericportis.com/etc/smashing-mag-picture-examples/variable-size.html
  26. 26 http://ericportis.com/etc/smashing-mag-picture-examples/variable-size.html
  27. 27 http://ericportis.com/etc/smashing-mag-picture-examples/variable-size.html
  28. 28 https://github.com/ResponsiveImagesCG/picture-element/issues/85
  29. 29 https://github.com/ResponsiveImagesCG/picture-element/issues/86
  30. 30 http://www.w3.org/TR/css3-values/#lengths
  31. 31 http://www.w3.org/TR/css3-values/#viewport-relative-lengths
  32. 32 http://ericportis.com/etc/smashing-mag-picture-examples/absolute-and-fixed.html
  33. 33 http://ericportis.com/etc/smashing-mag-picture-examples/absolute-and-fixed.html
  34. 34 http://ericportis.com/etc/smashing-mag-picture-examples/absolute-and-fixed.html
  35. 35 http://caniuse.com/calc
  36. 36 http://dev.w3.org/csswg/css-values/#calc-notation
  37. 37 http://ericportis.com/etc/ipad-air-art-direction/ipadair_hero_a.jpg
  38. 38 http://ericportis.com/etc/ipad-air-art-direction/ipadair_hero_b.jpg
  39. 39 http://ericportis.com/etc/smashing-mag-picture-examples/art-direction.html
  40. 40 http://ericportis.com/etc/smashing-mag-picture-examples/art-direction.html
  41. 41 http://ericportis.com/etc/smashing-mag-picture-examples/art-direction.html
  42. 42 http://en.wikipedia.org/wiki/Internet_media_type
  43. 43 http://alistapart.com/article/pngopacity
  44. 44 http://responsiveimages.org
  45. 45 http://www.w3.org/community/respimg/
  46. 46 http://irc.lc/w3c/respimg/newb
  47. 47 https://github.com/ResponsiveImagesCG/picture-element/issues
  48. 48 http://responsiveimages.org
  49. 49 http://www.twitter.com/respimg

↑ Back to topShare on Twitter

Eric grew up on the outskirts of Urbana, Illinois, studied printmaking & drawing in St. Louis, and has been in sunny Denver, Colorado working for a little print shop since 2006.

Advertising
  1. 1

    We Do Better Web

    May 14, 2014 4:00 pm

    “Images have been the number one obstacle to implementing truly adaptable and performant responsive pages”: in a pure tech perspective, sure. Otherwise, there’s a bigger problem in IA. Going Mobile First takes a lot of work even before you get to write a single HTML file…

    0
  2. 2

    “Cropping” by not cropping – or rather pre-cropping, is a cop-out.

    Last year’s article on achieving this using SVG – http://demosthenes.info/blog/722/Art-Directed-Adaptive-Images-With-SVG-and-JavaScript – shows a better way, but ideally CSS would allow a crop of the image based on media queries, so that the crop could be adaptive as well.

    0
    • 3

      CSS provides a way to do this via the `clip` property:

      http://css-tricks.com/almanac/properties/c/clip/

      “Pre-cropping” saves bytes — if the crop is dramatic, it can save *a lot* of bytes. Why send pixels to users that they’ll never see?

      On the other hand, I am sympathetic to the idea that cropping is a layout/presentational concern and should be left out of markup entirely. If that level of separation is important to you, use `clip`!

      1
      • 4

        Yeah, CSS clip is a weird one – only works with position:absolute or position:fixed (and is specified to). Maybe if it could be used for relative or static positioned items then it would be perfect. Until then…

        0
  3. 5

    Matthew Giacomazzo

    May 14, 2014 5:40 pm

    It would be nice to see some demos of the markup actually used in the article. I was confused looking at the demo links until I found that the image switching was being done with custom JS at the bottom…

    2
    • 6

      Yeah — `picture` isn’t in any browsers, yet, so the demos are faking it. I should have used PictureFill!

      -1
  4. 7

    I think setting a bunch of different sources manually, for different devices scoping different layouts, is still quite clumsy, regardless … Nothing is better than a javascript solution that checks the dimensions of the area where the image is is to be loaded, the pixel-density of the device, and then injects an appropriate image src from an array of sizes. Flawless.

    3
    • 8

      I use this approach now, on my own site, but am looking forward to switching over to the new markup for a few reasons.

      • Javascript is fragile (https://twitter.com/etportis/status/450998082134495232)

      • `sizes` works with the pre-loader, rather than against it. Using the spec gets you get preloaded images rather than either double downloads or no-image fallbacks.

      • The browser will know more about a given user’s context than my JavaScript ever can; `srcset` + `sizes` gives it the flexibility to use that information when picking a source. e.g., a browser may pick a smaller source when bandwidth is tight.

      1
  5. 9

    Thanks @Eric for this post. Was just going through http://www.mobify.com/mobifyjs/v2/examples/ to learn about responsive images when I got your post in my RSS feed.

    0
  6. 10

    Hi Eric. Nice article.

    For those reading the comments could I point them in the way of http://www.resrc.it. A full browser supported solution you can use today (using JavaScript) and without all the HTML and image variations requiring to be created and specified in the markup.

    You’ll see in demo link below there is absolutely no reference to a pixel size, dpi or compression. This is all handled automatically (and can be overridden).

    Images are treated as sizeless.

    http://jsfiddle.net/7Befr/

    Obviously if JavaScript is an issue pixel size, dpi, compression, artdirection etc. can all be specified manually using the url API

    More demos here: http://www.resrc.it/demos

    2
  7. 11

    There is no such thing as a responsive photograph, which is what is so frequently used in these examples and it’s starting to worry me.

    A photograph is a completed scene. Whatever is within the edges of the frame is all required – that is how it was shot, or cropped, it has been designed in order to tell a story. Cropping this image however you see fit just to suit your personal tastes as a designer is an insult to the photographer as well as the viewer.

    If, however the image in question is an aesthetic embellishment of the design or article, do whatever you want, it doesn’t matter because it’s only there for window dressing.

    This whole experiment for years now has been barking up the wrong tree. Think about the image used in those early examples of the dog in front of The White House. The point of that image is the dog is in the context of The White House. Then viewports start getting smaller and the image becomes cropped where to the point of it just being the face of the dog. The dog no longer has context, it is now just a dog.

    Forget all these truly intelligent ideas of how to manipulate code and layout based on available space and start thinking about the content you are manipulating. Come on people, think about it. You don’t see anyone saying, hey all these words are ruining my design on small screens, can I take six words from either side of each line to make it fit? No. So stop trying to do it to photographs.

    I know this will go unheard and ignored, right up to the point where some smart alec has built a system and it crops an image so that a famous persons junk is the only thing in the shot on a small display but on a TV they’re stood in the middle of the Sahara.

    Think about the content – not the code.

    4
    • 12

      I once wrote, when considering art direction, “whatever happened to content-parity? Would you crop the Mona Lisa?” So I’m sympathetic to the view. But I’ve since changed my mind. “Nobody should be able to crop any image ever” is an awful hard line to take.

      This post, in particular, really helped me to see the benefits of (and historical precedence for) going beyond simple scaling when adapting imagery to fit new constraints: http://needmoredesigns.com/blog/early-responsive-design/

      0
    • 13

      @Andy, I like your thinking. I have seen that same White House dog picture and thought it was kind of a joke. I like you analogy of an image getting auto cropped with code and the subject is the “junk” of the person in the shot on a small screen because the code said ‘crop to center left and top of image’.
      This means any image you put into a website the subject would have to be dead center in every, single, image. Not going to happen. And as we all know the old adage, “Content Is King”, and it is true. I do think that we might need responsive images, but not in the way of cropping the image on the fly or prior to the image inputted into the page. Maybe smaller sizes of an image but not cropped. Like you said, you end up with just a face and the image loses it context. The White House dog just becomes a dog, and you get someones junk only in the shot of the code auto crops to the middle of an image.

      0
  8. 14

    While I can appreciate all the hard work for providing us so much flexibility when dealing with images, I doubt that front-end developers will go through so much pain to make each image fully optimized for all devices. Sizes attribute is by far the most complex and it seems that we need to do the browser work.
    So far I think I’d only use the 1x 2x for HD displays. Anything else is way too time consuming for being practical. I hope they are still working on it!

    0
  9. 16

    hey, i dont know why 1st you use srcset=”…” size=”(min-width: 36em) 33.3w

    and in the other example you use <source media="(min-width: 36em)" src="…"

    you cant achieve the same thing in the last example with the 1rst code?

    0
    • 17

      The media queries in `sizes` are attached to *lengths*. In that first example, we’re saying that above 36em, the image will be 33.3vw wide, but below it the image will be 100vw wide.

      The media queries in `media` are attached to the “ itself. We’re saying: above 36em, pick from these URLS. Below 36em, don’t.

      `sizes` simply gives information about your layout to the browser. `media` is a way for you to make explicit “art-direction” decisions, mandating that particular sources get loaded at particular viewport sizes — a guarantee you don’t get with `sizes`.

      Another way to think about it: images in a `srcset` should all be the “same” — scaled down versions of each other. But each should look “different”: cropped, or otherwise altered.

      Hope that helps!

      2
  10. 18

    Forget the front-end, I’m just trying to get around the nightmare this creates for the CMS!

    3
    • 19

      You may have already seen this, but Jason Grigsby wrote a great, high-level post about designing a responsive images backend:

      http://blog.cloudfour.com/8-guidelines-and-1-rule-for-responsive-images/

      1
    • 20

      That has always been my thinking if you are using a CMS. Especially if an the CMS created virtual paths to the images because they are stored in the DB.
      I have thought of a way to do this, but of course this is all about image management. You have to have 3 (or more) images and specify the sizes. In you CMS code you would have to specify the small, medium and large size, and on the back end have the admin select the 3 different image sizes (small, medium, large) that would go for the image. Then you would write you code for the CMS to add in the images in the element. In essence it would not be too difficult, HOWEVER, you have the overhead of image management. Which in most cases, a client in not going to want to use an imaging program to save 3 or more image sizes. I could be wrong, but in my experience, most clients are not fluent in Photoshop (expensive for one) and don’t want to deal with cropping or resizing images ( which may be were the maintenance income comes into play).

      1
      • 21

        In the case of WordPress, this is already done automatically, ie. you upload an image, WP resizes it, based on its given rules (or what you told it via the currently active theme, some plugin, WooCommerce etc. pp.). So essentially you are already getting a thumbnail, a middle-sized image and a max-size(d) image (plus the original, of corpse).

        Also see http://codex.wordpress.org/Post_Thumbnails#Linking_to_Post_or_Larger_Image

        (nope, I’m NOT gonna get into more detail on here – its already totally detailed in the WP Codex, and I’m not a keen wheel reinventor ;))

        cu, w0lf.

        0
    • 22

      I was thinking exactly the same, you don’t want to complicate the lives of web content editors if you can avoid it. It might be a while before CMS vendors pick up on this and include functionality that makes it possible for a content editor to upload one version of the image and including it on a page, making all the magic with srcsets etc happen behind the scenes. So today, this isn’t really an option for me in client projects.

      0
    • 23

      Actually it’s not that hard. I use ProcessWire for quite some time now and it has a beautiful plugin called Thumbnails. Essentially if gives the devs to define fixed image sizes. Once the user uploads a image, he gets links below the image, one for each size, with a preview on hovering over them. These links point to a site, where the user can recrop the picture to the defined size, if the automated crop doesn’t fit. Done. For three or four sizes, it’s not that much of a pain for them to check this. No photoshop usage needed, and if you want you could even add a minification process on top of the cropping.

      Minor lack of the plugin is, that you always need to define both dimensions of the image, but that’s fixable.

      0
    • 24
  11. 25

    I think the spec is pretty awful.

    > All in all, srcset, x, w, sizes, , source, media and type give us a rich set of tools

    Tools we already have in CSS. If they’d just give CSS a source attribute we could keep the DOM simple. CSS is the place for responsiveness and as for retina we have to go there anyway to handle the bg images.

    0
    • 26

      The problem with solving this in CSS is preloading. Preloading provides a huge performance boost. Switching out `src`s via CSS would mean that the in-HTML `src` gets preloaded, but the final image only *starts* loading *after* CSS has been parsed, resulting in a slow double download.

      Various solutions were floated that used *inline* CSS and a preparser that was smart enough to take it into consideration, but they were… ugly.

      3
    • 27

      Actually handling even retina-images in css is pretty bad. Html is for the content and with using background-images you remove this content from it. I understand your point, that responsiveness is part of the presentation-layer, but the css way of responsive images, by now, is quite poor.

      0
    • 28

      Agreed! This method is essentially inlining what should be CSS.

      It is a poor solution that will make redesigning pages more difficult, since you’ll have to edit HTML or code as well as CSS.

      Put all the sources in the HTML, but take the media queries out of HTMLand put them in the CSS where they belong. Use the nth-child selector or name attributes to identify each source image.

      -1
      • 29

        As long as an image is part of/vital to the content, it should not be declared in CSS as a background, but as an image. And as said, by specifying it’s source in CSS you loose all the advantages of preloading. Unfortunately at this point there is no perfect solution, but this is workable.

        0
  12. 30

    The only thing I don’t like about this approach (and responsive images in general), is that it’s tied in with the CSS media queries.

    Change a query in your CSS and you’d need to update all the queries in all your HTML files as well, that’s hard (if not impossible) to maintain or develop with.

    I’ve never been a proponent of introducing media queries directly into HTML, I’d rather see a reference. Something like a variable name that references a specific query that can be used globally (HTML, CSS, JS).

    E.g: (variable formatting is just an example)
    _some-query = ‘screen and (min-width: 40em)’;

    In CSS you could then use:
    @media _some-query {}

    HTML:

    JS:
    window.matchMedia(_some-query) {}

    Other than that, I like the write-up , but it’s fairly complex and the syntax becomes pretty elaborate.

    Also, just a little side-note: you use XHTML mark-up in your examples (self-closing img tag), that’s not valid in HTML5, better not use it ;-)

    1
  13. 32

    We are currently building a simple web service (RESTful JSON API) to help with this problem, it’s called Image Resizer:

    http://imageresizer.io/

    The way it works is you upload a single source image (your largest, HD version), then use the returned image ID to construct URLs which dynamically transform your image.

    For example, original image:
    http://img.imageresizer.io/nKJ5SlkdIO

    Half size:
    http://img.imageresizer.io/nKJ5SlkdIO?size=50%

    Crop a square:
    http://img.imageresizer.io/nKJ5SlkdIO?size=300×300

    Change image quality and/or format (resulting in 25% bandwidth reduction):
    http://img.imageresizer.io/nKJ5SlkdIO?size=300×300&quality=75
    http://img.imageresizer.io/nKJ5SlkdIO?size=300×300&format=webp

    We not only solve the 5 use cases presented in this article, but also go beyond:

    Circular cut outs without requiring HTML or CSS tricks:
    http://img.imageresizer.io/nKJ5SlkdIO?size=300×300&ellipse

    Customized SEO URLs:
    http://img.imageresizer.io/nKJ5SlkdIO/Lightbulb-moment-300×300.jpg

    Plus other on-the-fly features such as face detection and image filters.

    Eric, is this something you think yourself and/or your readers would be interested in?

    We want to gauge interest in our service, so if you have any feedback I’d love to hear it!

    Nick

    0
  14. 33

    While I can appreciate all the hard work for providing us so much flexibility when dealing with images, I doubt that front-end developers will go through so much pain to make each image fully optimized for all devices. Sizes attribute is by far the most complex and it seems that we need to do the browser work.
    So far I think I’d only use the 1x 2x for HD displays. Anything else is way too time consuming for being practical. I hope they are still working on it!

    Aamir Shahzad
    http://aamirshahzad.net

    0
  15. 34

    I did the same thing, viewed the source hoping to see the example on my desktop for srcset or sizes within the markup… but Matthew Giacomazzo pointed out its mimicking the behavior with Javascript.. Nonetheless I decided to use Picturefill to solve my problem (http://scottjehl.github.io/picturefill/).

    0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top