Menu Search
Jump to the content X X
Smashing Conf Barcelona

You know, we use ad-blockers as well. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. our upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

WebKit Has Implemented srcset, And It’s A Good Thing

WebKit has made some serious news by finally implementing the srcset attribute1. As Chair of the W3C’s Responsive Images Community Group, I’ve been alternately hoping for and dreading this moment for some time now. It turns out to be good news for all involved parties—the users browsing the Web, most of all.

As with all matters pertaining to “responsive images”: it’s complicated, and it can be hard keeping up with the signal in all the noise. Here’s what you need to know.

Further Reading on SmashingMag: Link

What Does It Do?

As originally proposed, the srcset attribute allowed developers to specify a list of sources for an image attribute, to be delivered based on the pixel density of the user’s display:

<img src="low-res.jpg" srcset="high-res.jpg 2x">

Not too scary, this markup. In plain English:

“Use low-res.jpg as the source for this img on low-resolution displays, and for any browser that doesn’t understand the srcset attribute. Use high-res.jpg as the source for this img on high-resolution displays in browsers that understand the srcset attribute.”

Things were starting to look scary, for a little while there. Due in part to high resolution devices, the average website is now nearly an entire megabyte of images6. Now developers can target users on high-resolution displays with a high-resolution image source. Meanwhile, users on lower pixel density displays won’t be saddled with the bandwidth cost of downloading a massive high-resolution image, without seeing any benefit.

Can’t We Do That With JavaScript?

On the surface, srcset isn’t doing anything special—it chooses an appropriate source from an attribute and swaps the contents of an img tag’s src. Swapping the contents of an attribute is something we’ve been doing with JavaScript since time immemorial. Well, since the 90s, anyway. So, what does this gain us?

We actually attempted this approach on BostonGlobe.com7, one of the earlier sites to make use of any sort of “responsive images” solution. Thanks to increasingly aggressive prefetching in several of the major browsers, an image’s src is requested long before we have a chance to apply any custom scripting: we would end up making two requests for every one image we displayed, defeating the entire purpose. I’ve documented some of those efforts elsewhere8, so I’ll spare you the gory details here.

Can’t We Do That With CSS?

“Yes” and “No.” We can do this with background images easily enough, using a combination of media queries concerned with pixel density. srcset as implemented by WebKit is very similar to the recent image-set feature they introduced to CSS. image-set allows you to specify a list of background image sources and resolutions and allow the browser to make the decision as to which one is most appropriate—pretty familiar stuff. We didn’t have anything along these lines for non-presentational content images, however, until now.

Using CSS to manage content images is broken by default, in terms of keeping our concerns separate. It’s an approach that may make perfect sense within the scope of a quick demo page, but stands to quickly spiral out of control in a production website. Having our CMS generate scores of stylesheets full of background images would be no picnic, from a developer standpoint. Worse, however, is that it would lead to requests for stylesheets and images that users may not need unless done very, very carefully. Beyond that, it renders our images—no pun intended—inaccessible to users browsing by way of assistive technologies.

The closest thing we’ve found to a CSS-based approach would swap an image’s sources based on values set in HTMLs data attributes, using some proposed CSS trickery9, much of which is only theoretical and may never happen. However, it still didn’t account for the the double download of high and low resolution image assets—the same issue we encountered with JavaScript. Even if a technique like Nicolas’ should become available to us, we’ll still face the same problems as many script-based solutions: attempting to work around a wasteful, redundant request.

What Does It Do About Bandwidth?

Regardless of screen density, there are a number of situations where lower resolution images sources may be preferable: a Retina MacBook Pro tethered to a 3G, for example, or an unstable conference WiFi network—both situations we’ve all been in plenty of times.

Beyond simply providing us with a sort of inline shorthand for resolution media queries, srcset accounts for bandwidth as well, in a sense. It’s buried in arcane spec-speak, but one of the really exciting facets of srcset is that it’s defined as a set of suggestions to the browser. The browser can then use environmental heuristics or a user preference to decide that it wants to fetch a lower resolution image despite a high-resolution display: envision a preference in your mobile browser allowing high-res images to only be requested while connected to WiFi, or a manual browser preference allowing you to only request low-resolution images when your connection is shaky.

Responsive Images10
Ideally, we’d love to send only those images to devices which are specifically resized for each screen resolution. The intention is to save bandwidth and allow the images to download faster on the targeted screen. A common use case for responsive images11.

This isn’t a part of WebKit’s early srcset implementation, but it does pave the way for their addition without requiring any changes to our markup. We, developers, can safely use srcset today, and these optimizations may come “for free” in the future.

What Does This Mean For The picture Element?

Here’s where things get interesting.

The version of srcset implemented by WebKit matches the original proposed use of srcset, and the version that the Responsive Images Community Group12 has been working towards. We can think of this incarnation of srcset as shorthand for the whole slew of media queries concerned with resolution, with one key difference where the browser can choose to override the applicable source based on user preference.

While this implementation matches the original srcset proposal, the current srcset spec attempts to expand the syntax to cover some of the use cases13 that the picture element fulfills, using a microsyntax that performs some—but nowhere near all—of the functions of media queries.

<img src="fallback.jpg" srcset="small.jpg 640w 1x, small-hd.jpg 640w 2x, large.jpg 1x, large-hd.jpg 2x" alt="…">

In our opinion not ideal, this markup pattern. We’re restricted to the equivalent of max-width media queries, pixels, and an inscrutable microsyntax, all for the sake of duplicating the function of media queries. Fortunately for us, neither Web developers nor browser reps are particularly fond of this overextended syntax—hopefully, it will never see the light of day.

The picture element exists to address these use cases using a more flexible—and familiar—syntax. picture uses media attributes on source elements, similar to the video element. This allows us to target image sources to a combination of factors: viewport height and/or width, in pixels or ems, using either min or max values—just like media queries in our CSS.

    <source src="med.jpg" media="(min-width: 40em)" />
    <source src="sm.jpg" />
    <img src="fallback.jpg" alt="" />

The picture specification was written with this reduced srcset syntax in mind, so it could be used on picture’s source elements as well as img elements.

    <source srcset="med.jpg 1x, med-hd.jpg 2x" media="(min-width: 40em)" /> 
    <source srcset="sm.jpg 1x, sm-hd.jpg 2x" /> 
    <img src="fallback.jpg" alt="" />

In concert, the two markup patterns give us an incredible amount of flexibility over what image sources we serve to users, depending on their context.

So This Is Good News.

Absolutely, it is. While srcset as implemented by WebKit doesn’t address to all the responsive images use cases14, it does represent a major step toward a long overdue solution—hopefully the first of many.

Let’s hope that other browsers follow WebKit’s lead in implementing this feature as it was originally proposed, and stay tuned to the Responsive Images Community Group’s homepage15 and Twitter account16 to keep tabs on the subject.

I also wrote about the issues with responsive images and the solutions we’ve come up with when working on the BostonGlobe website in the chapter “The Struggles and Solutions In Responsive Web Design” of the upcoming Smashing Book 417. Grab it, you won’t be disappointed.


Footnotes Link

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17

↑ Back to top Tweet itShare on Facebook

Mat “Wilto” Marquis is a designer-slash-developer working at Filament Group, in Boston. Mat is a member of the jQuery Mobile team, an active member of the open source community, and a contributor to A List Apart where he also acts as technical editor and curator. Mat's passion for responsive Web design has led him to chair the Responsive Images Community Group, where he’s helping the web design community deal with the complex topic of responsive images and working towards a standardized solution with the W3C.

  1. 1

    Andrea Giammarchi

    August 21, 2013 12:44 pm

    nice writeup and I would like to add something: WP8 Lumia 620 and others have 1.5x display while BB Z10 has 2.3x display … other vendors might have different density and 2X does **not** always scale.

    Actually, none of this srcset idea really scale as much as a bloody info from the UA could do: usable from the server in order to serve the best option without blowing HTML or making more requests than necessary.

    Cookie, JS and Server, anything could work better than this proposal **but** it is good somebody is taking this issue more seriously: about the time!

  2. 2

    Is this a typo?

    <source src="sm.jpg 1x, sm-hd.jpg 2x.jpg" />

    Seems like it should be:

    <source src="sm.jpg 1x, sm-hd.jpg 2x" />

  3. 6

    What does this mean in regards to real world implementation. Do self-updating browsers like chrome have this implementation in their current builds or does each webkit-based browser need to decide when it wants to flip the switch?

  4. 7

    Anthony Young

    August 21, 2013 1:08 pm

    This is great news :)

  5. 8

    Yes, I am so pumped about this!

    I haven’t had a “standard” way of dealing with responsive images, until now.

  6. 9

    Tomáš Kapler

    August 21, 2013 1:24 pm

    Webkit? Who uses webkit now? Not in chrome anymore nand who knows when/if it will be updated at ipad, iphone …? Or does it mean, it will soon be in the chrome/android/opera etc.?

    • 10

      Given Apple is a primary developer on WebKit I’d be expecting it to arrive in Safari and iOS pretty soon. Also, Google didn’t drop WebKit, they forked it, which should make it relatively easy at this early stage for them to merge this feature in to their fork, which hopefully they will do.

      • 11

        I don’t think so. This isn’t supported in iOS 7 Safari or the Safari that will ship with OS X Mavericks and Apple don’t usually make changes to Safari until the next version of iOS (iOS 8 which is about 12-months away)

        • 12

          Useless without support in iOS.
          Apple should make Safari an updatable app (like Chrome Android.)

        • 13

          Not necessarily true. Apple could easily (and has in the past) push out small updates, one of which could include this. It only coordinates major version releases with major OS releases, not ALL changes/updates.

    • 14

      I think a couple of people use Safari on iOS

  7. 15

    Good news indeed.

    Re your comments on background images being used in place of content images: “Beyond that, it renders our images—no pun intended—inaccessible to users browsing by way of assistive technologies.”

    That’s true in most implementations, but there are ways around that. See here: The accessible approach is to place the small image in the HTML, and then use media queries to hide/replace it with bigger images for larger displays.

    But obviously srcset is a much better solution. The above is really only workable on small static sites.

  8. 16

    Adam Piotr Zochowski

    August 21, 2013 3:42 pm

    So we are coming back to full circle. Early in web development we had lowsrc attribute of img tag. The idea was to, depending on screen capabilities, and bandwidth, to let browser pick the proper image. Either lowsrc (usually black and white or grayscale) or normal src.

    Now we are moving towards supposed better solution, handing higher resolutions, but still no conceptual fix for quality. Not everyone has bandwidth for full quality image downloads, and we need progressive quality support. Not just resolution changes.

    • 17


      You might want to double-check the section on how `srcset` handles bandwidth, where I touched on how the markup pattern allows the browser—which can gather bandwidth information across an entire browsing session and knows best what the user has available—to intervene and request the standard resolution source either based on a bandwidth threshold or a user preference. I go into it in more detail in the initial post where we combined the `srcset` and `picture` patterns:

  9. 18

    John Haugeland

    August 21, 2013 9:31 pm

    Maybe I’m missing something, but to do it in CSS, why not just set a class on the body “doubleRes” or whatever, then write rules like

    #someSprite { background: url(‘normalSprite.png’) … ; }
    .doubleRes #somesprite { { background: url(‘hiResSprite.png’) … ; }

    • 19

      Because images in CSS aren’t part of the content, they’re part of the visual style of the site. If someone turns off CSS, it doesn’t necessarily mean that they don’t want to see content images. An example may be images in an article, or images in a gallery.

      CSS retina images are definitely required for design, hi-res content images was the missing piece of the puzzle.

      • 20

        “If someone turns off CSS”
        That sounds pretty silly. Why would you do that? It’s like turning off javascript or cookies. If you do it, then don’t go on the internet. Keep up with evolution.

        • 21

          The answer is accessibility. Not everyone lives in your CSS wonderland.

          • 22

            Need a real-world case of a group of users who have CSS turned off but want to access hi-res images.

  10. 23

    Niels Matthijs

    August 21, 2013 10:42 pm

    So when a breakpoint changes (and/or one is added), the html has to be adapted. Sounds like a nightmare to me. On the other hand, it means CMS implementers finally have a good reason to charge for responsive design.

    • 24

      This isn’t to do with breakpoints at all. Starting with the Macbook Pro, there are now desktops with retina displays and so you cannot guarantee that a high-resolution screen will be a mobile/tablet (and so rely on media queries in their basic form).

      This srcset attribute is putting the power in the hands of the browser as to what image it should use – it’s just a suggestion. I.e. if the user is on a high-res screen, it *may* use the high-res image. Or if the user is on a high-res screen but is only tethered to 3G, the browser *may* decide to only use the low-res image.

      • 25

        Niels Matthijs

        August 22, 2013 12:26 am

        Hmmm, I assumed this would also solve the broader problem of responsive images, not just the retina/HD part. Should’ve paid better attention to the introduction I guess :)

        Not that this affects the core of my argument. If LG releases its Quad HD(?) smartphone screen it still means changing the html if you want to support it. And it still doesn’t incorporate any solutions for truly responsive images (responsive in relation to its available width – which is something entirely different from screen size, even on phones and tablets these days).

        • 26

          > Hmmm, I assumed this would also solve the broader problem of responsive images, not just the retina/HD part.

          Exactly—that’s why we still need `picture`! The two work together to fulfill all of the use cases that the RICG has laid out:

      • 27

        — “This isn’t to do with breakpoints at all.”

        The spec supports breakpoints so yes it does have something to do with it.

  11. 28

    This is yet another misfortune. Such things surface when people want to solve a problem but cannot do that right since critical parts are out of their control.

    If User does not like what she sees, who to blame? Bandwidth? Browser?

    Will you ride an elevator that considers a pressed button as a suggestion?

    As a user, I do not want any suggestions anywhere, be it OS, Browser, whatever. Computer is a machine and should not consider suggestions, it should execute commands, promptly and flawlessly.

    Why not just let me choose what I prefer – poor image now or a fine one later? Somebody wants to save a couple of cents on the server side?

    • 29

      > Why not just let me choose what I prefer – poor image now or a fine one later? Somebody wants to save a couple of cents on the server side?

      This is precisely what `srcset` being specced as a “suggestion” allows—the room for a user to set a preference, rather than the browser blindly requesting whatever the author specifies.

  12. 30

    What’s wrong with picture tags including a set of sources, just like audio and video?

    Taking your example of the picture element, srcset just messes this up with unnecessary styling concerns which have no place in the html.

    <source srcset="med.jpg 1x, med-hd.jpg 2x" media="(min-width: 40em)" />
    <source src="sm.jpg 1x, sm-hd.jpg 2x.jpg" />
    <img src="fallback.jpg" alt="" />

    Should be:

    <source src="med.jpg" width="2000px" height="1000px">
    <source src="sm.jpg" width="1000px" height="500px">
    <img src="fallback.jpg">

    This leaves the browser to decide which images to load, based on multiple factors like user preference, network, screen resolution, display intent as specified in CSS, not just an arbitrary scale based on screen resolutions at this point in time. It also matches far better with existing html, rather than inventing a new dsl within the srcset tag which mixes presentation with content.

  13. 31

    Richard peirce

    August 21, 2013 11:18 pm

    Seems like a step in a direction, but my concern is that there still needs to be 2 versions of an image, meaning twice the work if it needs changing or updating.
    I look forward to a day images could be recreated as svgs, job done! :)

  14. 32

    This is great news that this has finally made headway – I can’t believe it took so long. The beauty about if using a CMS, you can simply instruct it to regenerate double size images (if the original exists on the server), then just amend all image output code to include the srcset attribute.

    It’s even easier if you use something like Timthumb where you can dynamically get it to output the larger size for higher resolutions. e.g:

    (I tried to paste in the code here but it kept getting removed, so here it is:

  15. 33

    Oliver Foxley

    August 22, 2013 1:09 am

    I have read lots about the responsive javascript solutions and it seems one of the main disadvantages listed every time is the fact that the low res image is initially downloaded in the src attribute. Why not just replace it with a 1×1 gif or something which is peanuts to download and can be cached? The data-src attribute contains the high res src – if that isn’t available knock the ‘2x’ off the end of the filename in the js and use that as the src instead. My solution uses CSS media queries and js for detection and falls back for non JS users. The disadvantage is images aren’t shown immediately but it’s still quick even on a slow connection and in my mind a small price for cross browser compatibility. I do like the idea of srcset taking into account bandwidth too though.

  16. 34

    I have my reservations on this becoming a standard, it’s fine in the sand box where it is right now, but there are serious impracticalities from a content editor perspective and whilst I am all for people exploring how we improve the quality of imagery on the web and thinking of user scenarios of viewing the content but there seems like there has been little consideration into how content is created and published.

    That’s been the problem since the first retina/HD displays hit the high street.

    There is a deeper conversation around ‘hd’ images, what are they anyway?

    • 35

      I couldn’t agree more. And as Richard Peirce mentions above, it seems to be doubling, or tripling, or even more the amount of work we need to do.

      I just can’t help but feel that this is actually a very short-sighted resolution. These aren’t responsive images. They don’t “respond” to anything. There’s just a couple of different versions of each image which the browser has a choice to pick from.

      Personally I believe the wizards who make things so, should look at extending progressive JPEGs somehow. I’m going out on a limb here and talking about things I’m really not qualified to discuss in depth, but wouldn’t an actual solution be something which doesn’t require any more work than we already do?

      My vision of a responsive/progressive image is a way for the browser to somehow determine the level of detail each progressive step displays, and then simply load the image through to the minimum required detail for its particular context.

  17. 36

    I want my lowsrc attribute back!
    HTML 3.2 FTW!

  18. 37

    This is a very eloquent solution…for now. But, as someone who’s been working with digital image formats for close to 20yrs I still think that in the not too distant future this will all be solved at the image format level. My bet is on a variation of the 32bit image architecture used in the special effects, gaming and 3D imaging fields (OpenEXR comes to mind). These formats hold massive amounts of information on the light and color of the scene. Adding info on resolution and removing unneeded information shouldn’t be that hard, it could even be incorporated into the png format I suspect. It’s just a matter of time…and work of course, It would be nice to see our Web Tech community sit down with the digital imaging community, have a couple of drinks and work this out.

  19. 38

    “Thanks to increasingly aggressive prefetching in several of the major browsers, an image’s src is requested long before we have a chance to apply any custom scripting”

    Why browsers are still doing this so aggressively and without any discernment is beyond me. Seems that’s something they would all be working to fix.

  20. 39

    Will picture elements have layout _before_ any sources have been requested?

    I think it’s a bit insane that img elements to this day still do not have any layout before the source gets requested (and enough image data has been read) – eventhough attributes (height/width) or CSS rules (max-width:100%;height:auto) are available!?

    It causes a seperate reflow for each image on a page – that’s just batsh*t crazy – especially considering all the other advances that are being made (picture, srcset, defer).

  21. 40

    I am in agreement with @Oliver Foxley”. But the disadvantage is big enough to leave the dynamic image loading to browsers, which IMHO is a perfect solution. I would grab this move with both hands.
    So, how does it work in the browser ? Chrome/Safari pick up the srcset parameter instead of src .

  22. 41

    Does this work with svg images? It would be awesome if I could just set the srcset to an svg and have every resolution covered.

  23. 42

    Ty Fairclough

    August 30, 2013 12:54 am

    This seems so outdated before it has even begun. For me the solution needs to be flanked in a unified way. I hoped Google’s WebP + Webkit would be the answer, but its fallen short for my desires.

    I want an extended single png file format that is backward compatible can specify multiple crops, sizes, resolutions (and more). No multiple images to maintain, no extra syntax (simple is beautiful), no javascript no server side work arounds. Just an image and a browser.

    Is that so much to ask?

  24. 43

    Any idea if Webkit browsers have or will be smart enough to use the HD images when printing?

  25. 44

    IMHO all this is going in the wrong direction. The same way the content encoding or compression are negotiated the image resolution (thinking about screen pixel/css pixel ratio: 1x, 1.5x, 2x …) could be negotiated or announced to the server, based on real screen resolution, bandwith o just user preferences. JPEG and PNG progressive (or interlaced) formats could be used and “chunked” to give the required amount of screen pixels on the server side. Nothing new to implement in browsers, just add few bytes to the img header request. We are already juggling with “vary” for caches and proxies, so it’s not a big difference in that sense. We don’t really need a new tag or refurbish the old img tag, just need to think again the way the resource is served.
    As I see it, each srcset chain element doesn’t really mean “it’s a different size for another display”, it means “it’s a different IMAGE RESOURCE for another display”, wich semantically disturbs me. Could be an elephant or a fly, depending on your screen. I think it’s better a single resource/url with certain negotiated properties (amount of pixels you want and so file size given) than any other.
    Right now you could do that writing your own server module and detecting the user agent (well, “wondering” user agent based on request header with all it’s problems and lies). X-UP-devcap-screenpixels, UA-pixels, X-JPHONE-DISPLAY or some other header should become standard -and real- to help with this. When we get a good module to serve chunched-valid JPEG/PNG images -and for sure we will soon- we’ll forget the srcset attribute and the picture tag.


↑ Back to top