Keeping The Big <picture> SmallHow To Avoid Duplicate Downloads In Responsive Images

Advertisement

The <picture> element is a new addition to HTML5 that’s being championed by the W3C’s Responsive Images Community Group1 (RICG). It is intended to provide a declarative, markup-based solution to enable responsive images without the need of JavaScript libraries or complicated server-side detection.

The <picture> element supports a number of different types of fallback content, but the current implementation of these fallbacks is problematic. In this article, we’ll explore how the fallbacks work, how they fail and what can be done about it.

The <picture> Element And Fallback Content

Like <video> and <audio>, <picture> uses <source> elements to provide a set of images that the browser can choose from. The <source> elements may optionally contain type and media attributes to let the browser know the file type and media type of the source, respectively. Given the information in the attributes, the browser should render the first <source> with a supported file type and matching media query. For example:

<picture>
    <source src="landscape.webp" type="image/webp" media="screen and (min-width: 20em) and (orientation: landscape)" />
    <source src="landscape.jpg" type="image/jpg" media="screen and (min-width: 20em) and (orientation: landscape)" />
    <source src="portrait.webp" type="image/webp" media="screen and (max-width: 20em) and (orientation: portrait)" />
    <source src="portrait.jpg" type="image/jpg" media="screen and (max-width: 20em) and (orientation: portrait)" />
</picture>

For situations in which a browser doesn’t know how to deal with <picture> (or <video> or <audio>) or cannot render any of the <source> elements, a developer can include fallback content. This fallback content is often either an image or descriptive text; if the fallback content is an <img>, then a further fallback is provided in the alt attribute (or longdesc), as normal.

<picture>
    <source type="image/webp" src="image.webp" />
    <source type="image/vnd.ms-photo" src="image.jxr" />
    <img src="fallback.jpg" alt="fancy pants">
</picture>

The <picture> element differs from <video> and <audio> in that it also allows srcset. The srcset attribute enables a developer to specify different images based on a device’s pixel density. When creating a responsive image using both <picture> and srcset, we might expect something like the following:

<picture>
    <source srcset="big.jpg 1x, big-2x.jpg 2x, big-3x.jpg 3x" type="image/jpeg" media="(min-width: 40em)" />
    <source srcset="med.jpg 1x, med-2x.jpg 2x, med-3x.jpg 3x" type="image/jpeg" />
    <img src="fallback.jpg" alt="fancy pants" />
</picture>

The idea behind a <picture> example like this is that exactly one image should be downloaded, according to the user’s context:

  • Users with <picture> support and a viewport at least 40 ems wide should get the big image.
  • Users with <picture> support and a viewport narrower than 40 ems should get the med image.
  • Users without <picture> support should get the fallback image.

If the browser chooses to display the big or med source, it can choose an image at an appropriate resolution based on the srcset attribute:

  • A browser on a low-resolution device (such as an iMac) should show the 1x image.
  • A browser on a higher-resolution device (such as an iPhone with a Retina display) should show the 2x image.
  • A browser on a next-generation device with even higher resolution should show the 3x image.

The benefit to the user is that only one image file is downloaded, regardless of feature support, viewport dimensions or screen density.

The <picture> element also has the ability to use non-image fallbacks, which should be great for accessibility: if no image can be displayed or if a user needs a description of an image, then a <p> or <span> or <table> or any other element may be included as a fallback. This allows for more robust and content-appropriate fallbacks than a simple alt attribute.

The Fallback Problem

Right now, the <picture> element is not supported in any shipped browsers. Developers who want to use <picture> can use Scott Jehl2’s Picturefill3 polyfill. Also, Yoav Weiss4 has created a Chromium-based prototype reference implementation5 that has partial support for <picture>. This Chromium build not only shows that browser support for <picture> is technically possible, but also enables us to check functionality and behavior against our expectations.

When testing examples like the above in his Chromium build, Yoav spotted a problem: even though <picture> is supported, and even though one of the first two <source> elements was being loaded, the fallback <img> was also loaded. Two images were being downloaded, even though only one was being used.

networkpane1-5006
Larger view7.

This happens because browsers “look ahead” as HTML is being downloaded and immediately start downloading images. As Yoav explains:

“When the parser encounters an img tag it creates an HTMLImageElement node and adds its attributes to it. When the attributes are added, the node is not aware of its parents, and when an ‘src’ attribute is added, an image download is immediately triggered.”

This kind of “look ahead” parsing works great most of the time because the browser can start downloading images even before it has finished downloading all of the HTML. But in cases where an img element is a child of <picture> (or <video> or <audio>), the browser wouldn’t (currently) care about the parent element: it would just see an img and start downloading. The problem also occurs if we forget about the parent element and just consider an <img> that has both the src and srcset attributes: the parser would download the src image before choosing and downloading a resource from srcset.

<picture>
    <source srcset="big.jpg 1x, big-2x.jpg 2x, big-3x.jpg 3x" media="(min-width: 40em)" />
    <source srcset="med.jpg 1x, med-2x.jpg 2x, med-3x.jpg 3x" />
    <img src="fallback.jpg" alt="fancy pants" />
    <!-- fallback.jpg is *always* downloaded -->
</picture>

<img src="fallback.jpg" srcset="med.jpg 1x, med-2x.jpg 2x, med-3x.jpg 3x" alt="fancy pants" />
<!-- fallback.jpg is *always* downloaded -->

<video>
    <source src="video.mp4" type="video/mp4" />
    <source src="video.webm" type="video/webm" />
    <source src="video.ogv" type="video/ogg" />
    <img src="fallback.jpg" alt="fancy pants" />
    <!-- fallback.jpg is *always* downloaded -->
</video>

In all of these cases, we would have multiple images being downloaded instead of just the one being displayed. But who cares? Well, your users who are downloading extra content and wasting time and money would care, especially the ones with bandwidth caps and slow connections. And maybe you, too, if you’re paying for the bandwidth you serve.

A Potential Solution

This problem needs both short- and long-term solutions.

In the long term, we need to make sure that browser implementations of <picture> (and <video> and <audio>) can overcome this bug. For example, Robin Berjon8 has suggested that it might be possible to treat the contents of <picture> as inert, like the contents of <template>, and to use the Shadow DOM (see, for example, “HTML5’s New Template Tag: Standardizing Client-Side Templating9”). Yoav has suggested using an attribute on <img> to indicate that the browser should wait to download the src.

While changing the way the parser works is technically possible, it would make the implementation more complicated. Changing the parser could also affect JavaScript code and libraries that assume a download has been triggered as soon as a src attribute is added to an <img>. These long-term changes would require cooperation from browser vendors, JavaScript library creators and developers.

In the short term, we need a working solution that avoids wasted bandwidth when experimenting with <picture> and srcset, and when using <video> and <audio> with <img> fallbacks. Because of the difficulty and time involved in updating specifications and browsers, a short-term solution would need to rely on existing tools and browser behaviors.

So, what is currently available to us that solves this in the short term? Our old friends <object> and <embed>, both of which can be used to display images. If you load an image using these tags, it will display properly in the appropriate fallback conditions, but it won’t otherwise be downloaded.

Different browsers behave differently according to whether we use <object>, <embed> or both. To find the best solution, I tested (using a slightly modified version of this gist10) in:

  • Android browser 528.5+/4.0/525.20.1 on Android 1.6 (using a virtualized Sony Xperia X10 on BrowserStack)
  • Android browser 533.1/4.0/533.1 on Android 2.3.3 (using a virtualized Samsung Galaxy S II on BrowserStack)
  • Android browser 534.30/4.0/534.30 on Android 4.2 (using a virtualized LG Nexus 4 on BrowserStack)
  • Chrome 25.0.1364.160 on OS X 10.8.2
  • Chromium 25.0.1336.0 (169465) (RICG Build) on OS X 10.8.2
  • Firefox 19.0.2 on OS X 10.8.2
  • Internet Explorer 6.0.3790.1830 on Windows XP (using BrowserStack)
  • Internet Explorer 7.0.5730.13 on Windows XP (using BrowserStack)
  • Internet Explorer 8.0.6001.19222 on Windows 7 (using BrowserStack)
  • Internet Explorer 9.0.8112.16421 on Windows 7 (using BrowserStack)
  • Internet Explorer 10.0.9200.16384 (desktop) on Windows 8 (using BrowserStack)
  • Opera 12.14 build 1738 on OS X 10.8.2
  • Opera Mobile 9.80/2.11.355/12.10 on Android 2.3.7 (using a virtualized Samsung Galaxy Tab 10.1 on Opera Mobile Emulator for Mac)
  • Safari 6.0.2 (8536.26.17) on OS X 10.8.2
  • Safari (Mobile) 536.26/6.0/10B144/8536.25 on iOS 6.1 (10B144) (using an iPhone 4)
  • Safari (Mobile) 536.26/6.0/10B144/8536.25 on iOS 6.1 (10B141) (using an iPad 2)

I ran five tests:

  1. <picture> falls back to <object>
  2. <picture> falls back to <embed>
  3. <picture> falls back to <object>, which falls back to <embed>
  4. <picture> falls back to <object>, which falls back to <img>
  5. <picture> falls back to <img>

I found the following support:

What the user sees

Test 1 Test 2 Test 3 Test 4 Test 5
Android 1.6 fallback image fallback image fallback image fallback image fallback image
Android 2.3 fallback image fallback image fallback image fallback image fallback image
Android 4.2 fallback image fallback image fallback image fallback image fallback image
Chrome 25 fallback image fallback image fallback image fallback image fallback image
Chromium 25 (RICG) picture/source image picture/source image picture/source image picture/source image picture/source image
Firefox 19 fallback image fallback image fallback image fallback image fallback image
IE 6 no image no image no image no image fallback image
IE 7 no image no image no image no image fallback image
IE 8 fallback image no image fallback image fallback image fallback image
IE 9 fallback image fallback image (cropped and scrollable) fallback image fallback image fallback image
IE 10 fallback image fallback image (cropped and scrollable) fallback image fallback image fallback image
Opera 12.1 fallback image fallback image fallback image fallback image fallback image
Opera Mobile 12.1 fallback image fallback image fallback image fallback image fallback image
Safari 6 fallback image fallback image fallback image fallback image fallback image
Safari iOS 6 (iPad) fallback image fallback image fallback image fallback image fallback image
Safari iOS 6 (iPhone) fallback image fallback image fallback image fallback image fallback image

HTTP requests

Test 1 Test 2 Test 3 Test 4 Test 5
Android 1.6 1 GET 1 GET 1 GET 2 GETs 1 GET
Android 2.3 1 GET 1 GET 1 GET 2 GETs 1 GET
Android 4.2 1 GET 1 GET 1 GET 2 GETs 1 GET
Chrome 25 1 GET 1 GET 1 GET 2 GETs 1 GET
Chromium 25 (RICG) 1 GET 1 GET 1 GET 2 GETs 2 GETs
Firefox 19 1 GET 1 GET 2 GETs 2 GETs 1 GET
IE 6 1 GET none 1 GET 1 GET 1 GET
IE 7 1 GET none 1 GET 1 GET 1 GET
IE 8 1 GET none 1 GET 1 GET 1 GET
IE 9 1 HEAD, 1 GET 1 GET 1 HEAD, 1 GET 1 HEAD, 2 GETs 1 GET
IE 10 1 HEAD, 1 GET 1 GET 1 HEAD, 1 GET 1 HEAD, 2 GETs 1 GET
Opera 12.1 1 GET 1 GET 1 GET 2 GETs 1 GET
Opera Mobile 12.1 1 GET 1 GET 1 GET 2 GETs 1 GET
Safari 6 1 GET 1 GET 1 GET 2 GETs 1 GET
Safari iOS 6 (iPad) 1 GET 1 GET 1 GET 2 GETs 1 GET
Safari iOS 6 (iPhone) 1 GET 1 GET 1 GET 2 GETs 1 GET

Image-aware context menu

Test 1 Test 2 Test 3 Test 4 Test 5
Android 1.6 yes yes yes yes yes
Android 2.3 yes yes yes yes yes
Android 4.2 yes yes yes yes yes
Chrome 25 no no no no yes
Chromium 25 (RICG) no no no no no
Firefox 19 yes yes yes yes yes
IE 6 no no no no yes
IE 7 no no no no yes
IE 8 yes no yes yes yes
IE 9 yes yes yes yes yes
IE 10 yes yes yes yes yes
Opera 12.1 yes yes yes yes yes
Opera Mobile 12.1 yes no yes yes yes
Safari 6 no no no no yes
Safari iOS 6 (iPad) no no no no yes
Safari iOS 6 (iPhone) no no no no yes

Making Sure The Content Is Accessible

Although the specifics of how to provide fallback content for <picture> are still being debated11 (see also this thread12), I wanted to test how Apple’s VoiceOver performed with different elements. For these experiments, I checked whether VoiceOver read alt attributes in various places, as well as fallback <span> elements. Unfortunately, I wasn’t able to test using other screen readers or assistive technology, although I’d love to hear about your experiences.

Read by VoiceOver

alt on picture alt on source (picturesource) alt on object (pictureobject) alt on embed (pictureembed) alt on embed (pictureobjectembed)
Chrome 25 no no yes yes no
Chromium 25 (RICG) yes no no no no
Firefox 19 no no yes yes no
Opera 12.1 no no no no no
Safari 6 no no yes yes no
Safari iOS 6 (iPad) no no yes yes no
Safari iOS 6 (iPhone) no no yes yes no
Read by VoiceOver
alt on img (pictureobjectimg) alt on img (pictureimg) span (picturespan) span (pictureobjectspan)
Chrome 25 no yes yes no
Chromium 25 (RICG) no no no no
Firefox 19 no yes yes no
Opera 12.1 no no yes no
Safari 6 no yes yes no
Safari iOS 6 (iPad) no yes yes no
Safari iOS 6 (iPhone) no yes yes no

Bulletproof Syntax

Based on these data, I’ve come up with the following “bulletproof” solution:

<picture alt="fancy pants">
    <!-- loaded by browsers that support picture and that support one of the sources -->
    <source srcset="big.jpg 1x, big-2x.jpg 2x, big-3x.jpg" type="image/jpeg" media="(min-width: 40em)" />
    <source srcset="med.jpg 1x, med-2x.jpg 2x, big-3x.jpg" type="image/jpeg" />

    <!-- loaded by IE 8+, non-IE browsers that don’t support picture, and browsers that support picture but cannot find an appropriate source -->
    <![if gte IE 8]>
    <object data="fallback.jpg" type="image/jpeg"></object>
    <span class="fake-alt">fancy pants</span>
    <![endif]>

    <!-- loaded by IE 6 and 7 -->
    <!--[if lt IE 8]>
    <img src="fallback.jpg" alt="fancy pants" />
    <![endif]-->
</picture>

.fake-alt {
    border: 0;
    clip: rect(0 0 0 0);
    height: 1px;
    margin: -1px;
    overflow: hidden;
    padding: 0;
    position: absolute;
    width: 1px;
}

Here we have a <picture> element, two sources to choose from for browsers that support <picture>, a fallback for most other browsers using <object> and a <span> (see note just below), and a separate <img> fallback for IE 7 and below. The empty alt prevents the actual image from being announced to screen readers, and the <span> is hidden using CSS (which is equivalent to HTML5 Boilerplate13’s .visuallyhidden class) but still available to screen readers. The <embed> element is not needed.

(Note: The use of the <span> as a fake alt is necessary so that VoiceOver reads the text in Opera. Even though Opera has a relatively small footprint, and even though it’s in the process of being switched to WebKit, I still think it’s worth our consideration. However, if you don’t care about supporting that particular browser, you could get rid of the <span> and use an alt on the <object> instead (even though that isn’t strictly allowed by the specification). This is assuming that the <span> and alt have the same content. If you have a richer fallback element, such as a <table>, using both it and a non-empty alt attribute might be desirable.)

A similar solution should also work with <audio>, although <img> fallbacks for that element are, admittedly, rare. When dealing with <video>, the problem goes away if our fallback image is the same as our poster image. If these may be the same, then the “bulletproof” syntax for <video> would be this:

<video poster="fallback.jpg">
    <!-- loaded by browsers that support video and that support one of the sources -->
    <source src="video.mp4" type="video/mp4" />
    <source src="video.webm" type="video/webm" />
    <source src="video.ogv" type="video/ogg" />

    <!-- loaded by browsers that don't support video, and browsers that support video but cannot find an appropriate source -->
    <img src="fallback.jpg" alt="fancy pants" />
</video>

However, if your <video> needs a separate fallback and poster image, then you might want to consider using the same structure as the <picture> solution above.

Note that <video> and <audio> don’t have alt attributes, and even if you add them, they will be ignored by VoiceOver. For accessible video, you might want to look into the work being done with Web Video Text Tracks14 (WebVTT).

Unfortunately, extensive testing with <video> and <audio> elements is beyond the scope of this article, so let us know in the comments if you find anything interesting with these.

How Good (Or Bad) Is This Solution?

Let’s get the bad out of the way first, shall we? This solution is hacky. It’s obviously not workable as a real, long-term solution. It is crazy verbose; no one in their right mind wants to code all of this just to put an image on a page.

Also, semantically, we really should use an <img> element to display an image, not an <object>. That’s what <img> is for.

And there are some practical issues:

  • Chrome and Safari won’t show proper context menus for the images, meaning that users won’t be able to open or save them easily.
  • IE 9 and 10 send an extra HEAD request along with the GET request.
  • Using a <span> as a fake alt is pretty sketchy, and although it worked for my tests in VoiceOver, it could potentially cause other accessibility problems.

All that being said, as a short-term solution, it’s not too bad. We get these benefits:

  • A visible image in every browser is tested (<picture> and <source> when supported, and the fallback otherwise).
  • Only one HTTP GET request in every browser is tested (and the extra HEAD request and response in IE are tiny).
  • VoiceOver is supported (and is hopefully supported with other screen readers).

networkpane2-50015
Larger view16.

The semantics of the solution, while not ideal, are not horrible either: the HTML5 specification17 states that an <object> “element can represent an external resource, which, depending on the type of the resource, will either be treated as an image, as a nested browsing context, or as an external resource to be processed by a plugin” (emphasis mine).

And although the <span> is not as nice as a real alt attribute, using a visually hidden element for accessibility is not uncommon. Consider, for example, “Skip to content” links that are visibly hidden but available to screen readers.

Next Steps

The best part about this solution, though, is that it highlights how bad the current situation is. This is a real problem, and it deserves a better solution than the monstrosity I’ve proposed.

We need discussion and participation from both developers and browser vendors on this. Getting support from browser makers is crucial; a specification can be written for any old thing, but it doesn’t become real until it is implemented in browsers. Support from developers is needed to make sure that the solution is good enough to get used in the real world. This consensus-based approach is what was used to add the <main> element to the specification recently; Steve Faulkner discusses this process a bit in his excellent interview with HTML5 Doctor18.

If you’re interested in helping to solve this problem, please consider joining the discussion:

The next step towards a long-term solution is to achieve consensus among developers and browser vendors on how this should work. Don’t get left out of the conversation.

Thanks to fellow RICG members Yoav Weiss, Marcos Cáceres and Mat Marquis for providing feedback on this article.

(al)

↑ Back to topShare on Twitter

Dave is a full-stack developer in Toronto. His day job is in a Knowledge Translation research program, where he gets to pursue his interests in making the web more usable, useful, and accessible. Dave has a beard, but it's not because he thinks it looks good; he's just too lazy to shave.

  1. 1

    Every day I see easier solutions to old problems whose “solutions” were varied and debatable, I’m ever so excited to see W3C doing what they do best to move the web forward in a positive and consistent manner. The idea of having a picture element that behaves as beautifully as video does today, is wonderful. I hope the gurus, devs, and browsers updates of tomorrow can do at least a good a job with as they did with , hopefully with a smoother transition and more consensus as well.

    5
    • 2

      Is the ideal solution not much simpler than all this?

      1. Browser determines the correct image size based on bandwidth, screen size, orientation, user preference, etc.
      2. Browser tells webserver: I want to ‘Photo.jpg’ at (i.e.) resolution 1024×768.
      3. Webserver converts ‘Photo.jpg’ to 1024×768 and sends it to the browser.

      This way you only need ONE single high resolution image on the webserver. I don’t see why it’s the responsibility of a developer make sure that there is a specific image for each device/orientation. It’s nice in case you want to control over this process, but in most cases developers have more important things to do than this.

      I’m probably oversimplifying things, but I don’t see why this is technically so difficult.

      6
      • 3

        Thanks for your comment, Reinout. I think that absolutely is a valid way to tackle this, but it comes with its own problems. First many (if not most) front-end developers don’t have access to their server config to set up something like this. Second, it really only tackles the a resolution-switching scenario; check http://usecases.responsiveimages.org/ to see some of the other use cases, such as art direction. For cases where you just want simple resolution switching, and where you have access to server config, I think an approach like you describe could work well.

        3
        • 4

          That’s why I called it ‘ideal solution’. Imo, developers should not need access to a webserver. The webserver should ‘just’ support resizing of an image.

          Regarding your argument about other use cases: these can be added to html as well (i.e. img orientation=”portrait” ).

          Anyway, your article is very valuable. I don’t want to start a discussion about an ‘ideal’ solution here. But sometimes, as a very inexperienced web developer, it’s difficult to understand that critical (and old?) problems like this do not have a proper solution yet.

          3
          • 5

            I think that’s why this kind of discussion is so important, and why collaboration between designers, developers, and browser makers is so important. The last thing anybody wants is to ship a new feature or “solution” that isn’t workable.

            0
  2. 6

    Bullet proof?
    I am not so sure about this whole solution at all,
    In order for us to have to enter one image we have to have multiple versions of the same image in multiple formats and resolutions (disk space usage problem).
    Remembering the order and the whole code or trying to show the right implementation could also be a nightmare.
    I think we create more work and rules to remember than solving the problem as a whole.

    Not convinced that this is the best way forward. (sorry)

    4
    • 7

      Thanks for your comment, Val. Just because it’s bulletproof doesn’t mean it isn’t cumbersome. :) I totally agree that this is way overcomplicated, and barely usable; I’m just saying it works. As I said in the article, nobody really wants to do this just to get an image on the screen. The good thing is, responsive images *can* be much simpler. If you don’t care about different formats, just use one. If all you need is resolution switching, you can just use srcset on an img element. To see some of the use cases for responsive images, check out http://usecases.responsiveimages.org/.

      Regarding storing extra versions on the server: yes this is a hassle and possible expense for devs, but the tradeoff could be a better experience for your users. For me, that’s worth it.

      Anyway, please consider taking part in the RICG discussions. We’d love more input and involvement!

      0
      • 8

        There’s not really a need to store extra versions on the server if there’s no interest in art direction. Simply upload a large version, and use something like Timthumb (with security in mind) to produce the downsized versions. Then let the picture tag serve up the right one.

        Granted this is now in the realms of using another language (in this case PHP), and if caching is used to speed up generation time (which it should be), then that’ll use up space. But it should cut down on having to upload multiple versions of the same file.

        2
    • 9

      You do realize that disk space is the least expensive commodity around the market, don’t you?

      -1
  3. 12

    “no one in their right mind wants to code all of this just to put an image on a page.”
    Glad you said it. I do respect the thought and creativity put into this though. I feel this is an initial step to a simple and elegant solution. You need these brainstorms before the eureka moment.

    6
  4. 13

    Really? I solved this problem like six months ago when I release retinise.js – http://www.dahliacreative.com/retinisejs – and it’s a lot less hassle than whatever you wrote…

    I did send it to you guys when I released it, clearly you just ignored me….

    4
    • 14

      Hi Simon, thanks for your comment. I took a look at retinajs — it’s a nice little plugin! From what I can see, the use case you are tackling is resolution-switching, and I think you’ve handled it nicely. (There are also some other use cases for picture besides resolution switching, notably art direction. See http://usecases.responsiveimages.org/.) It might be worth exploring converting this into a polyfill for the srcset syntax.

      The downside with a JavaScript solution like this is that a user without JavaScript won’t get *any* image. It also means that the page won’t benefit from any image preloading, so the user may have to wait longer for the image to download. An HTML-based solution could avoid those problems but, until that happens, JavaScript is all we have on the client-side.

      Please consider stopping by the RICG IRC channel (irc://irc.w3.org/respimg) to chat; we’d love to discuss your ideas further.

      0
      • 15

        Christoph Wagner

        May 11, 2013 2:26 am

        > The downside with a JavaScript solution like this is that a user without JavaScript won’t get *any* image.

        The noscript tag should take care of that, wouldn’t it?

        <noscript>
        <img src=”/img/path/non-retina.jpg” alt=”My Image” />
        </noscript>

        0
      • 17

        I also currently use a hand-coded solution for images on retina and similar displays and on responsive layouts. I’m not sure what’s the percentage of users that have javascript off or such an old browser that doesn’t support it, but 6 years ago that was under 3%, or just under 1.5% in Europe.

        I got only one question, is it worth losing time to have a solution that works for those who don’t have javascript on? I don’t think so.

        When we do have a neat semantic solution that’s supported natively by all major browsers we can ditch javascript, but for now I don’t think it’s worth it to overload the html sent to the browser with sooo much extra info just to render a picture.

        3
    • 18

      I see you leave the src attribute empty in your initial markup, is not bad in a SEO perspective? Is it? I guess is the only downside of your approach.

      I used retina.js once but it has the double image download issue.

      0
  5. 19

    Daniel Schwarz

    May 10, 2013 8:06 am

    I hope that I don’t start a war by saying this, but…

    I thought that the aim of responsive design was to offer cross-platform support, for a better and consistent user interface, that we might be past the day where we’d have to create a different CSS for each browser and each device on each version of each device. Responsive design was a good practice to implement, and for sure it’s been adopted by many professional designers, but now there’s “fallbacks”? Doesn’t this negate the point of responsive design?

    Of course, by no means I am saying that I’m an expert, because I’m not. This is simply my opinion. But, I think that responsive design has gone too far and fell back on itself.

    Just my opinions,

    -Daniel Schwarz (founder of Airwalk Design)

    1
    • 20

      Thanks for your comment, Daniel. In many ways, responsive design is about progressive enhancement; the point is to ensure a good, usable experience for everybody, regardless of device, platform, browser, screen size, etc. Part of that means that when a new HTML element is introduced, we need to worry about how it will display in browsers that don’t support it. This is why a fallback img is needed. The text fallbacks are needed for people that have images turned off, use a screenreader, etc. Hope that helps!

      1
      • 21

        Daniel Schwarz

        May 11, 2013 3:06 pm

        Absolutely, I agree. However, elements have been introduced, then deprecated (and then even re-introduced), and if we go on what Val said, which I totally agree with, that this only creates more work and more rules, then these over-complicated (as you described it) solutions will likely stick around for a while.

        I agree with what you’re trying to achieve, it worked with HTML5 Drag & Drop (boy that was complicated), it was very unsupportive at first, but then became widely adopted by all major browsers, but only because it accomplished a useful UI task. This, however, I don’t feel meets a real need, and comes with more issues than it solves.

        That being said, this was a great article.

        0
        • 22

          Thank you very much!

          I guess I was slightly unclear above: I think the stuff I proposed with using object instead of img, and using IE conditional comments, is over-complicated. I think the picture tag itself is just the right amount of complicated; yes, it’s verbose, but I think it handles the task relatively elegantly (though if the media queries could be moved out of the markup, that would be even better).

          In terms of the need, I disagree. I think the amount of attention the picture element, picturefill, and responsive images in general have received indicates that there *is* a need here. It doesn’t mean every img needs to be replaced by picture, but there are cases where it is appropriate.

          0
          • 23

            Daniel Schwarz

            May 13, 2013 9:38 am

            What you said about cases, is exactly what I mean. But maybe I’m under the impression that there are less cases where the picture element would be needed, than there actually are. It must be an issue that is clearly present, but I myself haven’t seen enough of. But that’s why this article exists, to raise awareness for it.

            Thanks for writing it :)

            1
  6. 24

    Nelson Hereveri

    May 10, 2013 9:31 am

    It’s sad to see that those who try to help with the compilation of data presented without further criticize the obvious arguments presented in the comments.

    First thanks for the data collected, this information will surely help you a lot to objective improvement and testing of code.

    As stated in the article the proposed solution has never tried to be a neat solution in terms of HTML5 and CSS3, but a real solution considering the technology available at the time.
    Although the comments are correct, it is likely that you misunderstood the situation where users are, who do not necessarily understand the operation of your browser, and just need a picture or video.

    1
  7. 25

    This picture element is reminiscent of microformats … a push to making content that is created primarly once, in such a way that it could be used in other ways beyond the creators long-term imagination. This never actually stopped (nor does it stop now) people from using content in places and ways in whic hthe creator of content never intended. These solutions are great on paper, but people can still (and do) use websites and content that is not optimised for them … I can still use websites that were created 10 years ago. I can still watch video that was created in PAL 4:3 and I am sure when video becomes 8K+ we will all laugh at the feable efforts right now to provide content in multiple resolutions and still dispappoint people in 2 years time.

    Images created in numerous resolutions under 4K right now will also look embaressing when wall-sized displays become the norm in a few years … and with that, people will still be using PAL 4:3 video and 1080 video that they own along with photos they took on their 4MB camera phone … because it was already shot at that resolution and people still value it to keep it and tweet about it in the next 2 years.

    These excessive new elements are great on paper, but like all other technologies 10 years ago, will fall far short of what we expect in the next 10 years, so I am not worrying. Img tag content 10 years ago still works now, puts less stress on html markup and server calls and storage space … that in itself makes img tag approach more effiecient in many ways.

    0
  8. 26

    This is nice, I will test it out and play around with it, on another note as another commenter point it out…Why? I understand the whole point is to provide a better experience, but, I don’t get the reason of having to manage multiple images just to display one, it only creates more work and hassle for later maintenance, when most of the times the difference is not even noticeable. Let alone it becomes more confusing when the project is finished and handed over to clients who wish to make the maintenance themselves.

    1
    • 27

      If it’s a situation where the difference isn’t noticeable, then maybe that situation doesn’t call for a responsive image. It’s a solution to fit certain problems, but not to replace the img tag entirely! But sometimes it can be appropriate.

      Yes, managing multiple images can be a pain, but there are lots of reasons why you might want to do this. I believe it’s important to respect your users and give them a good experience. Having an image that’s too small or inappropriate for their viewing context could look bad. Having an image that’s too large could waste their bandwidth, drain their battery, and slow-down page load time. In my opinion, creating and maintaining a few extra image files when appropriate is a small price for giving users a good experience that will hopefully keep them coming back.

      In terms of handing over to clients, I agree that it could be problematic. Hopefully what we’ll see is automated support for this type of feature getting built into content management systems. Support for the picture element is already in Drupal 8, which is a great start.

      0
  9. 28

    IMG tags have been supported by browsers for long, but no browser has ever been supporting the PICTURE tag.

    -6
  10. 29

    I see a solution. Once browsers implement the picture tag, they’ll take care of that. Voila :)

    2
    • 30

      Like they have for img fallbacks for video ;)

      In truth, I think you’re right — this will get solved, and hopefully as soon as picture gets implemented. Most of what I’m hoping for with this is a discussion about the issues at hand. As I said, I think the “solution” here isn’t really that useful for the real world.

      0
  11. 31

    This is very nice to see, but that use of media queries frightens me. We’re throwing something in HTML that depends completely on the design of the page. Why should the document markup need to be concerned that a 200px image fits best in the product description box with a 40em viewport?

    I was expecting that the best approach, in general, would be to specify dimensions for different picture sources. (Dimensions being optional but, obviously, important if we want to actually save bandwidth). Then the browser could pick the appropriate image to display based on the size it is going to be rendered at — and other stuff, perhaps, such as the zoom level and the strengths / weaknesses of the browser’s scaling algorithm. The person writing markup, then, only needs to worry about the size of each picture source.

    Is that a thing we will be able to do with this feature? What is the use case for media queries here?

    0
  12. 33

    Sorry but this is just brain masturbation. Replacing a tag by a dozen lines of code (“bulletproof syntax”) is just ridiculous. This is neither bulletproof, nor BSproof.
    Why not just keep using a server side script and let your server provide each device the best picture regarding their screen def ? Like Matt Wilcox’s Adaptative Image. This is the easiest solution and by far the best from now. I just don’t see the point. IE will still be here for a couple years to pissus off anyway..

    0
    • 34

      I suppose we have a different definition of bulletproof. I simply meant that it was a solution that would work; I also mentioned that I thought it was crazy and not realistic to implement. Whether it’s BS or not depends on whether it’s helpful for people’s projects; I take it from your comment that you think the entire picture tag is BS, which is your call.

      I think Matt Wilcox’s Adaptive Image technique is awesome. Unfortunately, using it means that you need access to server configuration, and that’s just not the reality for many devs. In my opinion, a client-side solution is necessary. Picture is verbose, but it addresses a lot of use cases. If all you need is simple resolution switching, img srcset may be more appropriate.

      So far I think the combination of picture and srcset are our best options for the client-side. If you think that they can be approved upon, we’d welcome your input and participation at the RICG. Discussion and collaboration are the best way we can get working solution solutions.

      0
  13. 35

    Anybody willing to wade into the mess that is responsive web development and come up with workable solutions to never ending problems deserves a tip of my hat. Nicely written David, i very much enjoyed it. I have dreams where we have one browser and new code is implemented all at one time and works perfectly:D *sigh*. Thanks again.. i look forward to using picture and will think back to this article when I’m taking the element for granted!

    3
  14. 37

    What you really need is an intelligent designer; briefed in what’s cost effective and not- the server can handle the chug. This is a nice article, with some excellent work but simply hiring a designer who knows or listens to limits will solve the situation. eg-” we we can do you 4 sizes at these breakpoints, and you can expect some scaling in between”. Excellent piece of work though, all the way through. As you say, when support settles off we can do things right!

    0
    • 38

      Thanks! I think that’s a very good point. While automating responsive image generation is a key component in a lot of use cases, it’s key not to underestimate the importance of good design, planning, and client education. No one solution will work for everybody, so it’s important to figure out what the best approach is given the constraints of a project.

      0
  15. 39

    Woah, this is quite comprehensive! Just goes to show why i visit this website the first thing in the morning, compared to other web developer sites. It’s rare to find somebody else be this in depth.
    Thanks for the article!

    0
  16. 41

    Is there any javascript solution, that can handle all attributes of the picture/source construction? I knew, there are solutions, that can handle mediaqueries, but I haven’t found anything, that can handle srcsets and the type attribute.

    0
    • 42

      Check out my branch of picturefill at https://github.com/nwtn/picturefill/ for type and srcset support. Unfortunately I haven’t looked at it in a bit and I think there are some bugs, but it should at least provide a jumping off point for you. If you end up finding any bugs with it, feel free to file a pull request with fixes. :)

      0
  17. 43

    I took Thomas Fuchs’s advice in his book “Retrinafy Your Apps” to NOT make multiple versions of a content image but make one version and make the quality slightly less than half to accommodate Retina Display images with very acceptable results.

    I utilize the element, especially when W3C earlier this month finally begun steps to reconsider it, for UI elements where it’s mission critical for high fidelity of the text and other brittle raster-dependent elements need to always be sharp.

    If necessary, say for a model that really wants her (or his) image to be retina ready) I from time to time use retina.js w/ PaperClip being a Rails developer to use a conditional @2x approach using the data attribute at the expense of the possibility of double loading occurring.

    What you think of this approach, David Newton (Thomas Fuch’s one image for both pixel density scenarios except UI elements) ?

    0
    • 44

      Is that the same as the compressive images approach described at http://filamentgroup.com/lab/rwd_img_compression/? If so, I think it’s really clever and interesting. Unfortunately, I haven’t had a chance to play with it much, but I’ve heard really good things about it. Has it been working out well for you?

      0
      • 45

        Correct; pretty much I heard of it first by Thomas Fuch. Some recently have merely referred to the technique merely as the ‘downsampling’ approach, including a recent article by NetTuts that also speaks of this method when it comes to designing for high-DPI screen devices.

        Ideally, I’ve find it invaluable to think about when it comes to content images; for UI-critical elements or elements that involve text, this techniques becomes brittle in usefulness, which Fuch warns about.

        0
  18. 46

    Mauricio Wolff

    May 22, 2013 5:38 am

    Was thinking about simplicity… what’s the opinion on a standard user agent component informing resolution/pixel density? Like “Android XYZ { “resolution”: “1024×768″, “pixdensity”: “1.5x” }” So we could parse it server side, client side, as JSON…

    The server could serve the right image based on the request headers, and JS could detect changes and fetch additional images in case of orientation changes.

    0
  19. 47

    Nice article, thanks! but sure, we must find a simpler and easy way to work this through, when the time comes to design and develop for glasses (maybe just now) and watches and other devices away from flat screens we are going to get into a serious time consuming problem

    0
  20. 48

    Nathanael Jones

    June 2, 2013 7:18 am

    Why didn’t you compare/test against the noscript tag as a fallback solution?

    0
  21. 49

    Adding to the discussion, the BBC released the code for their “placeholder” method for Responsive Images. (This was released long after this SmashingMagazine article was posted):
    http://responsivenews.co.uk/post/58244240772/imager-js

    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