Abstract

When authors adapt their sites for high-resolution displays, they often need to be able to use different assets representing the same image. We address this need for adaptive, bitmapped content images by adding a srcset attribute to the img element.

Status of This document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.

If you wish to make comments regarding this document in a manner that is tracked by the W3C, please submit them via using our public bug database. If you cannot do this then you can also e-mail feedback to public-html-comments@w3.org (subscribe, archives), and arrangements will be made to transpose the comments to our public bug database. All feedback is welcome.

Work on extending this specification typically proceeds through extension specifications which should be consulted to see what new features are being reviewed.

The bulk of the text of this specification is also available in the WHATWG HTML Living Standard, under a license that permits reuse of the specification text.

Implementors should be aware that this specification is not stable. Implementors who are not taking part in the discussions are likely to find the specification changing out from under them in incompatible ways. Vendors interested in implementing this specification before it eventually reaches the Candidate Recommendation stage should join the aforementioned mailing lists and take part in the discussions.

This is a work in progress! For the latest updates from the HTML WG, possibly including important bug fixes, please look at the editor's draft instead.

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

The latest stable version of the editor's draft of this specification is available at http://dev.w3.org/html5/srcset/. There are various ways to follow the change history for this specification:

Browsable version-control record of all changes:
Github repository (real-time updates): https://github.com/w3c/html/commits/w3c-srcset

The W3C HTML Working Group is the W3C working group responsible for this specification's progress along the W3C Recommendation track. This specification is the 28 February 2013 First Public Working Draft.

Work on this specification is also done at the WHATWG. The W3C HTML working group actively pursues convergence with the WHATWG, as required by the W3C HTML working group charter. There are various ways to follow this work at the WHATWG:

This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

Table of Contents

  1. 1 Introduction
  2. 2 Terminology
  3. 3 Conformance requirements
  4. 4 Additions to the img element
  5. 5 Obtaining images
  6. 6 Processing the image candidates
  7. 7 Adaptive images
  8. References
  9. Acknowledgements

1 Introduction

This section is non-normative.

When authors create sites which adapt to different viewport sizes and display resolutions, they often need to be able to use different resources representing the same image. Ideally, User Agents would avoid fetching the unused resources. This specification defines srcset, a new attribute for the img element, to address this need in the case of content images. (There are several existing mechanisms to address this need for CSS images.)

The srcset attribute allows authors to provide, in a compact manner, multiple variants of the same image at differing resolutions or for different viewport dimensions. User Agents may make their resource selection before fetching any of the resources, thus avoiding multiple resource loads and the associated performance problems in constrained bandwidth environments.

2 Terminology

The conformance requirements, conformance classes, definitions, dependencies, terminology, and typographical conventions described in the HTML5 specification apply to this specification. [HTML5]

Interfaces are defined in terms of Web IDL. [WEBIDL]

3 Conformance requirements

All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.

The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC2119. The key word "OPTIONALLY" in the normative parts of this document is to be interpreted with the same normative meaning as "MAY" and "OPTIONAL". For readability, these words do not appear in all uppercase letters in this specification. [RFC2119]

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

For example, were the spec to say:

To eat an orange, the user must:
1. Peel the orange.
2. Separate each slice of the orange.
3. Eat the orange slices.

...it would be equivalent to the following:

To eat an orange:
1. The user must peel the orange.
2. The user must separate each slice of the orange.
3. The user must eat the orange slices.

Here the key word is "must".

The former (imperative) style is generally preferred in this specification for stylistic reasons.

Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)

4 Additions to the img element

Content attributes:
srcset
DOM interface:
partial interface HTMLImageElement {
           attribute DOMString srcset;
};

The image given by the src and srcset attributes is the embedded content.

The srcset attribute may be present. If present, its value must consist of one or more image candidate strings, each separated from the next by a "," (U+002C) character. This attribute allows authors to provide alternative images for environments with smaller screens or screens with higher pixel densities.

The srcset IDL attribute must reflect the content attribute of the same name.

The srcset attribute allows authors to provide a set of images to handle graphical displays of varying dimensions and pixel densities.

The attribute essentially takes a comma-separated list of URLs each with one or more descriptors giving the maximum viewport dimensions and pixel density allowed to use the image. From the available options, the user agent then picks the most appropriate image. If the viewport dimensions or pixel density changes, the user agent can replace the image data with a new image on the fly.

To specify an image, give first a URL, then one or more descriptors of the form 100w, 100h, or 2x, where "100w" means "maximum viewport width of 100 CSS pixels", "100h" is the same but for height, and "2x" means "maximum pixel density of 2 device pixels per CSS pixel".

The IDL attribute complete must return true if any of the following conditions is true:

Otherwise, the attribute must return false.

The value of complete can thus change while a script is executing.

An image candidate string consists of the following components, in order, with the further restrictions described below this list:

  1. Zero or more space characters.
  2. A valid non-empty URL referencing a non-interactive, optionally animated, image resource that is neither paged nor scripted.
  3. Zero or more space characters.
  4. Optionally a width descriptor, consisting of: a space character, a valid non-negative integer representing the width descriptor value, and a U+0077 LATIN SMALL LETTER W character.
  5. Zero or more space characters.
  6. Optionally a height descriptor, consisting of: a space character, a valid non-negative integer representing the height descriptor value, and a U+0068 LATIN SMALL LETTER H character.
  7. Zero or more space characters.
  8. Optionally a pixel density descriptor, consisting of: a space character, a valid floating-point number giving a number greater than zero representing the pixel density descriptor value, and a U+0078 LATIN SMALL LETTER X character.
  9. Zero or more space characters.

Each image candidate string must have at least one of the three optional descriptors. There must not be two image candidate strings in a srcset attribute whose width descriptor value, height descriptor value, and pixel density descriptor value are each identical to their counterpart in the other image candidate string; for the purposes of this requirement, omitted width descriptors and height descriptors are considered to have the value "Infinity", and omitted pixel density descriptors are considered to have the value 1.

In this example, a banner that takes half the viewport is provided in two versions, one for wide screen and one for narrow screens.

<h1><img alt="The Breakfast Combo"
         src="banner.jpeg"
         srcset="banner-HD.jpeg 2x, banner-phone.jpeg 100w, banner-phone-HD.jpeg 100w 2x"></h1>

5 Obtaining images

This section supersedes the text in HTML5 which defines how the image data of img elements is obtained, so that it is sensitive to both the src and srcset attributes.

When the user agent is to update the image data of an img element, it must run the following steps:

  1. Return the img element to the unavailable state.

  2. If an instance of the fetching algorithm is still running for this element, then abort that algorithm, discarding any pending tasks generated by that algorithm.

  3. Forget the img element's current image data, if any.

  4. If the user agent cannot support images, or its support for images has been disabled, then abort these steps.

  5. If the element has a srcset attribute specified, then let selected source and selected pixel density be the URL and pixel density that results from processing the image candidates, respectively. Otherwise, if the element has a src attribute specified and its value is not the empty string, let selected source be the value of the element's src attribute, and selected pixel density be 1.0. Otherwise, let selected source be null and selected pixel density be undefined.

  6. Let the img element's last selected source be selected source and the img element's current pixel density be selected pixel density.

  7. Resolve selected source, relative to the element. If that is not successful, abort these steps.

  8. Let key be a tuple consisting of the resulting absolute URL, the img element's crossorigin attribute's mode, and, if that mode is not No CORS, the Document object's origin.

  9. If the list of available images, contains an entry for key, then set the img element to the completely available state, update the presentation of the image appropriately, queue a task to fire a simple event named load at the img element, and abort these steps.

  10. Asynchronously await a stable state, allowing the task that invoked this algorithm to continue. The synchronous section consists of all the remaining steps of this algorithm until the algorithm says the synchronous section has ended. (Steps in synchronous sections are marked with ⌛.)

  11. ⌛ If another instance of this algorithm for this img element was started after this instance (even if it aborted and is no longer running), then abort these steps.

    Only the last instance takes effect, to avoid multiple requests when, for example, the src, srcset, and crossorigin attributes are all set in succession.

  12. ⌛ If selected source is null, then set the element to the broken state, queue a task to fire a simple event named error at the img element, and abort these steps.

  13. Fire a progress event named loadstart at the img element.

  14. Do a potentially CORS-enabled fetch of the absolute URL that resulted from the earlier step, with the mode being the state of the element's crossorigin content attribute, the origin being the origin of the img element's Document, and the default origin behaviour set to taint.

    The resource obtained in this fashion, if any, is the img element's image data. It can be either CORS-same-origin or CORS-cross-origin; this affects the origin of the image itself (e.g. when used on a canvas).

    Fetching the image must delay the load event of the element's document until the task that is queued by the networking task source once the resource has been fetched (defined below) has been run.

    This, unfortunately, can be used to perform a rudimentary port scan of the user's local network (especially in conjunction with scripting, though scripting isn't actually necessary to carry out such an attack). User agents may implement cross-origin access control policies that are stricter than those described above to mitigate this attack, but unfortunately such policies are typically not compatible with existing Web content.

    The first task that is queued by the networking task source while the image is being fetched must set the img element's state to partially available.

    If the resource is in a supported image format, then each task that is queued by the networking task source while the image is being fetched must update the presentation of the image appropriately (e.g. if the image is a progressive JPEG, each packet can improve the resolution of the image). In addition, if the resource is CORS-same-origin, each such task must fire a progress event named progress at the img element.

    Furthermore, the last task that is queued by the networking task source once the resource has been fetched must additionally run the steps for the matching entry in the following list:

    If the download was successful and the user agent was able to determine the image's width and height
    1. Set the img element to the completely available state.

    2. Add the image to the list of available images using the key key.

    3. If the resource is CORS-same-origin: fire a progress event named load at the img element.

      If the resource is CORS-cross-origin: fire a simple event named load at the img element.

    4. If the resource is CORS-same-origin: fire a progress event named loadend at the img element.

      If the resource is CORS-cross-origin: fire a simple event named loadend at the img element.

    Otherwise
    1. Set the img element to the broken state.

    2. If the resource is CORS-same-origin: fire a progress event named load at the img element.

      If the resource is CORS-cross-origin: fire a simple event named load at the img element.

    3. If the resource is CORS-same-origin: fire a progress event named loadend at the img element.

      If the resource is CORS-cross-origin: fire a simple event named loadend at the img element.

    On the other hand, if the resource type is multipart/x-mixed-replace, then each task that is queued by the networking task source while the image is being fetched must also update the presentation of the image, but as each new body part comes in, it must replace the previous image. Once one body part has been completely decoded, the user agent must set the img element to the completely available state and queue a task to fire a simple event named load at the img element.

    The progress and loadend events are not fired for multipart/x-mixed-replace image streams.

    Otherwise, either the image data is corrupted in some fatal way such that the image dimensions cannot be obtained, or the image data is not in a supported file format; the user agent must set the img element to the broken state, abort the fetching algorithm, discarding any pending tasks generated by that algorithm, and then queue a task to first fire a simple event named error at the img element and then fire a simple event named loadend at the img element.

6 Processing the image candidates

When the user agent is required to process the image candidates of an img element's srcset attribute, the user agent must run the following steps, which return a URL and pixel density (null and undefined respectively if no selection can be made):

  1. Let input be the value of the img element's srcset attribute.

  2. Let position be a pointer into input, initially pointing at the start of the string.

  3. Let raw candidates be an initially empty ordered list of URLs with associated unparsed descriptors. The order of entries in the list is the order in which entries are added to the list.

  4. Splitting loop: Skip whitespace.

  5. Collect a sequence of characters that are not space characters, and let that be url.

  6. If url is empty, then jump to the step labeled descriptor parser.

  7. Collect a sequence of characters that are not "," (U+002C) characters, and let that be descriptors.

  8. Add url to raw candidates, associated with descriptors.

  9. If position is past the end of input, then jump to the step labeled descriptor parser.

  10. Advance position to the next character in input (skipping past the "," (U+002C) character separating this candidate from the next).

  11. Return to the step labeled splitting loop.

  12. Descriptor parser: Let candidates be an initially empty ordered list of URLs each with an associated pixel density, and optionally an associated width, height, or both. The order of entries in the list is the order in which entries are added to the list.

  13. For each entry in raw candidates with URL url associated with the unparsed descriptors unparsed descriptors, in the order they were originally added to the list, run these substeps:

    1. Let descriptor list be the result of splitting unparsed descriptors on spaces.

    2. Let error be no.

    3. Let width be absent.

    4. Let height be absent.

    5. Let density be absent.

    6. For each token in descriptor list, run the appropriate set of steps from the following list:

      If the token consists of a valid non-negative integer followed by a U+0077 LATIN SMALL LETTER W character
      1. If width is not absent, then let error be yes.

      2. Apply the rules for parsing non-negative integers to the token. Let width be the result.

      If the token consists of a valid non-negative integer followed by a U+0068 LATIN SMALL LETTER H character
      1. If height is not absent, then let error be yes.

      2. Apply the rules for parsing non-negative integers to the token. Let height be the result.

      If the token consists of a valid floating-point number followed by a U+0078 LATIN SMALL LETTER X character
      1. If density is not absent, then let error be yes.

      2. Apply the rules for parsing floating-point number values to the token. Let density be the result.

    7. If width is still absent, set it to Infinity.

    8. If height is still absent, set it to Infinity.

    9. If density is still absent, set it to 1.0.

    10. If error is still no, then add an entry to candidates whose URL is url, associated with a width width, a height height, and a pixel density density.

  14. If the img element has a src attribute whose value is not the empty string, then run the following substeps:

    1. Let url be the value of the element's src attribute.

    2. Add an entry to candidates whose URL is url, associated with a width Infinity, a height Infinity, and a pixel density 1.0.

  15. If candidates is empty, return null as the URL and undefined as the pixel density and abort these steps.

  16. If an entry b in candidates has the same associated width, height, and pixel density as an earlier entry a in candidates, then remove entry b. Repeat this step until none of the entries in candidates have the same associated width, height, and pixel density as an earlier entry.

  17. Optionally, return the URL of an entry in candidates chosen by the user agent, and that entry's associated pixel density, and then abort these steps. The user agent may apply any algorithm or heuristic in its selection of an entry for the purposes of this step.

    This allows a user agent to override the default algorithm (as described in subsequent steps) in case the user agent has a reason to do so. For example, it would allow the user agent in highly bandwidth-constrained conditions to intentionally opt to use an image intended for a smaller screen size, on the assumption that it'll probably be good enough. Implementors are urged to avoid doing this if at all possible, to let authors have predictable results. The results of using an image intended for a different viewport size can be, at a minimum, aesthetically displeasing.

    This clause is not necessary to select images that are of lower pixel density than the display can handle, because the definition of pixel density below is also left up to the user agent. This step is only needed to allow user agents to pick images intended for viewports with other dimensions.

  18. Let max width be the width of the viewport, and let max height be the height of the viewport. [CSS]

  19. If there are any entries in candidates that have an associated width that is less than max width, then remove them, unless that would remove all the entries, in which case remove only the entries whose associated width is less than the greatest such width.

  20. If there are any entries in candidates that have an associated height that is less than max height, then remove them, unless that would remove all the entries, in which case remove only the entries whose associated height is less than the greatest such height.

  21. If there are any entries in candidates that have an associated pixel density that is less than a user-agent-defined value giving the nominal pixel density of the display, then remove them, unless that would remove all the entries, in which case remove only the entries whose associated pixel density is less than the greatest such pixel density.

  22. Remove all the entries in candidates that have an associated width that is greater than the smallest such width.

  23. Remove all the entries in candidates that have an associated height that is greater than the smallest such height.

  24. Remove all the entries in candidates that have an associated pixel density that is greater than the smallest such pixel density.

  25. Return the URL of the sole remaining entry in candidates, and that entry's associated pixel density.

The user agent may at any time run the following algorithm to update an img element's image in order to react to changes in the environment. (User agents are not required to ever run this algorithm.)

  1. Asynchronously await a stable state. The synchronous section consists of all the remaining steps of this algorithm until the algorithm says the synchronous section has ended. (Steps in synchronous sections are marked with ⌛.)

  2. ⌛ If the img element does not have a srcset attribute specified, is not in the completely available state, has image data whose resource type is multipart/x-mixed-replace, or if its update the image data algorithm is running, then abort this algorithm.

  3. ⌛ Let selected source and selected pixel density be the URL and pixel density that results from processing the image candidates, respectively.

  4. ⌛ If selected source is null, then abort these steps.

  5. ⌛ If selected source and selected pixel density are the same as the element's last selected source and current pixel density, then abort these steps.

  6. Resolve selected source, relative to the element.

  7. ⌛ Let CORS mode be the state of the element's crossorigin content attribute.

  8. ⌛ If the resolve a URL algorithm is not successful, abort these steps.

  9. End the synchronous section, continuing the remaining steps asynchronously.

  10. Do a potentially CORS-enabled fetch of the resulting absolute URL, with the mode being CORS mode, the origin being the origin of the img element's Document, and the default origin behaviour set to taint.

    If this download fails in any way (other than the response code not being a 2xx code, as mentioned earlier), or if the image format is unsupported (as determined by applying the image sniffing rules, again as mentioned earlier), or if the resource type is multipart/x-mixed-replace, then abort these steps.

    Otherwise, wait for the fetch algorithm to queue its last task, and then continue with these steps. The data obtained in this way is used in the steps below.

  11. Queue a task to run the following substeps:

    1. If the img element's src, srcset, or crossorigin attributes have been set, changed, or removed since this algorithm started, then abort these steps.

    2. Let the img element's last selected source be selected source and the img element's current pixel density be selected pixel density.

    3. Replace the img element's image data with the resource obtained by the earlier step of this algorithm. It can be either CORS-same-origin or CORS-cross-origin; this affects the origin of the image itself (e.g. when used on a canvas).

    4. Fire a simple event named load at the img element.


The task source for the tasks queued by algorithms in this section is the DOM manipulation task source.

7 Adaptive images

This section is non-normative.

CSS and media queries can be used to construct graphical page layouts that adapt dynamically to the user's environment, in particular to different viewport dimensions and pixel densities. For content, however, CSS does not help; instead, we have the img element's srcset attribute. This section walks through a sample case showing how to use this attribute.

Consider a situation where on wide screens (wider than 600 CSS pixels) a 300×150 image named a-rectangle.png is to be used, but on smaller screens (600 CSS pixels and less), a smaller 100×100 image called a-square.png is to be used. The markup for this would look like this:

<figure>
 <img src="a-rectangle.png" srcset="a-square.png 600w"
      alt="Barney Frank wears a suit and glasses.">
 <figcaption>Barney Frank, 2011</figcaption>
</figure>

The problem with this is that the user agent does not necessarily know what dimensions to use for the image when the image is loading. To avoid the layout having to be reflowed multiple times as the page is loading, CSS and CSS media queries can be used to provide the dimensions:

<figure>
 <style scoped>
  #a { width: 300px; height: 150px; }
  @media all and (max-width: 600px) { #a { width: 100px; height: 100px; } }
 </style>
 <img src="a-rectangle.png" srcset="a-square.png 600w" id="a"
      alt="Barney Frank wears a suit and glasses.">
 <figcaption>Barney Frank, 2011</figcaption>
</figure>

Alternatively, the width and height attributes can be used to provide the width for legacy user agents, using CSS just for the user agents that support srcset:

<figure>
 <style scoped media="all and (max-width: 600px)">
  #a { width: 100px; height: 100px; }
 </style>
 <img src="a-rectangle.png" width="300" height="100"
      srcset="a-square.png 600w" id=a
      alt="Barney Frank wears a suit and glasses.">
 <figcaption>Barney Frank, 2011</figcaption>
</figure>

The srcset attribute is used with the src attribute, which gives the URL of the image to use for legacy user agents that do not support the srcset attribute. This leads to a question of which image to provide in the src attribute.

The answer that results in the least duplication is to provide the image suitable for an infinite width and infinite height viewport with a pixel density of 1 CSS pixel per device pixel:

<img src="pear-desktop.jpeg" srcset="pear-mobile.jpeg 720w, pear-tablet.jpeg 1280w"
     alt="The pear is juicy.">

However, if legacy mobile user agents are more important, one can list all three images in the srcset attribute, overriding the src attribute entirely. To do this, the widest image has to have the pixel density descriptor instead of the width, since there is no way to specify an infinite width explicitly:

<img src="pear-mobile.jpeg"
     srcset="pear-mobile.jpeg 720w, pear-tablet.jpeg 1280w, pear-desktop.jpeg 1x"
     alt="The pear is juicy.">

Since at this point the src attribute is actually being ignored entirely by srcset-supporting user agents, the src attribute can default to any image, including one that is neither the smallest nor biggest:

<img src="pear-tablet.jpeg"
     srcset="pear-mobile.jpeg 720w, pear-tablet.jpeg 1280w, pear-desktop.jpeg 1x"
     alt="The pear is juicy.">

The dimensions in the srcset attribute are the maximum (viewport) dimensions that an image is intended for. It is possible to think of the numbers as minimums, though... if the images are listed in order, then the minimum for an image is the dimension given for the previous image. This example attempts to demonstrate this by using the file names to show the minimum values for each image:

<img src="pear-tablet.jpeg"
     srcset="pear-min0.jpeg 720w, pear-min721.jpeg 1280w, pear-min1281.jpeg 1x"
     alt="The pear is juicy.">

References

All references are normative unless marked "Non-normative".

[CSS]
Cascading Style Sheets Level 2 Revision 1, B. Bos, T. Çelik, I. Hickson, H. Lie. W3C.
[HTML5]
HTML5, R. Berjon, T. Leithead, E. Doyle Navara, E. O'Connor, S. Pfeiffer. W3C.
[HTML]
(Non-normative) HTML, I. Hickson. WHATWG.
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels, S. Bradner. IETF.
[WEBIDL]
Web IDL, C. McCormack. W3C.

Acknowledgements

The existence of this specification is entirely due to Ian Hickson, who specified the srcset attribute in the WHATWG HTML Living Standard. This is an automated redaction of the relevant portions of that document. [HTML]