Responsive Images Community Group

The picture Element

Editor’s Draft, 19 December 2013

This version:
http://picture.responsiveimages.org
Editor’s Draft:
http://picture.responsiveimages.org
Test Suite:
None Yet
Editors:
Tab Atkins (Google)
(Mozilla)
Mat Marquis
Yoav Weiss
Version History:
Commit History
Github commits on Twitter
Participate:
Join the Responsive Images Community Group
Public Mailing List
IRC: #respimg on W3C’s IRC
Twitter
Github

Abstract

The picture element is intended to give authors a way to control which image resource a user agent presents to a user, based on media query and/or support for a particular image format.

The primary purpose of the picture element is to address use cases [respimg-usecases] that are left unaddressed by the srcset attribute [HTML]; the most important being art direction. Other use cases, such as matching media features and media types and matching on supported image formats, are also addressed by this specification.

Table of contents

1 Introduction

This specification provides developers with a means to declare multiple sources for an image, and, through [MEDIAQ] (CSS Media Queries), it gives developers control as to when those images are to be presented to a user. This is achieved by introducing the picture element to HTML, and by enhancing the source element to support specifying multiple source urls.

By relying on [MEDIAQ], a user agent can respond to changes in the browsing environment by selecting the image source that most closely matches the browsing environment - thus embodying a technique known as responsive web design directly in the HTML markup. Media features that a user agent can potentially respond to include, but are not limited to, pixel widths and heights, and pixel densities, as well as environmental lighting conditions, changes in orientation, and changes in media type such as going from screen to print.

The picture element remains backwards compatible with legacy user agents by degrading gracefully through fallback content (i.e., through the img element) while also potentially providing better accessibility than the existing img element.

This specification also defines the HTMLPictureElement interface, through which developers can interact with picture elements.

1.1 When to use picture

The picture element is intended primarily for art directing graphical content. For cases where a single image source is available, and where no responsive adoption is needed, authors are encouraged to use the img element instead.

1.2 Examples of usage

This example shows how to combine the picture element with the source element, while also providing fallback content for legacy user agents through the img element.
  <picture>
     <source media="(min-width: 45em)" src="large.jpg">
     <source media="(min-width: 18em)" src="med.jpg">
     <source src="small.jpg">
     <img src="small.jpg" alt="" width="500" height="500">
     <p>Accessible text</p>
  </picture>
This example shows how the picture element can be used with the srcset attribute to provide a range of sources suitable for a given media query:
  <picture>
     <source media="(min-width: 45em)" src="large-1.jpg, large-2.jpg 2x">
     <source media="(min-width: 18em)" src="med-1.jpg, med-2.jpg 2x">
     <source srcset="small-1.jpg, small-2.jpg 2x">
     <img src="small-1.jpg" alt="" width="500" height="500">
     <p>Accessible text</p>
  </picture>
This example shows how picture and other HTML elements can be used together.
  <figure>
      <picture>
         <source media="(min-width: 45em)" src="large-1.jpg, large-2.jpg 2x">
         <source media="(min-width: 18em)" src="med-1.jpg, med-2.jpg 2x">
         <source srcset="small-1.jpg, small-2.jpg 2x">
         <img src="small-1.jpg" alt="" width="200" height="200">
      </picture>
      <figcapture>A figure of a fox jumping over a lazy box.</figcaption>
  </figure>

Need a bunch more examples + explanation.

1.3 Relationship to srcset

The srcset attribute allows authors to define various image resources and “hints” that assist a user agent in determining the most appropriate image source to display. Given a set of image resources, the user agent has the option of either following or overriding the author’s declarations to optimize the user experience based on criteria such as display density, network connection type, user preferences, and so on.

The picture element defines conditions under which the use agent needs to follow the author’s explicit instructions when selecting which resource to display. This includes image sources with inherent sizes designed to align with layout variations specified in CSS media queries (see: design breakpoints, and relative units) or content variations for increased clarity and focus (i.e., art direction) based on the client’s viewport.

The proposed solutions are not mutually exclusive. They work together to address the complete set of use cases and requirements for responsive images (see [respimg-usecases]).

2 Definitions

The following terms are used throughout this specification so they are gathered here for the readers convenience. The following list of terms is not exhaustive; other terms are defined throughout this specification.

The follow terms are defined by the [HTML] specification: fallback content, and valid media query.

3 The picture Element

Name: picture
Categories: Flow content, Phrasing content, Embedded content, Palpable content
Contexts: Where embedded content is expected
Content Model: Zero or more source elements, followed by one img element.
Attributes: Global attributes

The picture element is a container which provides multiples sources to its contained img element, allowing the displayed image to vary based on the density of the screen or other environmental factors expressed as media queries.

Note: picture is somewhat different from the similar-looking elements video and audio. While all of them contain source elements, the syntax of the src attribute is different when the element is nested within picture, and the resource selection algorithm is different. As well, the picture element itself does not display anything; it merely provides a context for its contained img that enables it to choose from multiple source urls.

A picture element is associated with a list of source sets, which is a list of zero or more source sets.

A source set is a set of zero or more image sources, optionally a source size list, and optionally a media query.

An image source is a URL, and optionally either a density descriptor, or a width descriptor.

A source size list is a list of zero or more pairs of a media query and a <length>, and optionally a default <length>.

3.1 Sub-Algorithms

3.1.1 Selecting an Image Source

This is meant to be the HTML integration point.

When asked to select an image source for a given img element el, user agents must do the following:

  1. Update the list of source sets for el.
  2. If el’s list of source sets is empty,

    make the img throw an error, however that’s done.

    Exit this algorithm.
  3. Otherwise, take the first source set in el’s list of source sets and let it be source set.
  4. In a UA-specific manner, choose one image source from source set. Let this be selected source.
  5. The intrinsic width of el is the result of finding the effective size from source list. The intrinsic resolution of el is the density associated with selected source.
  6. Load the url of selected source, etc.

This just selects a single image and then sticks with it, unlike CSS’s image(), but similar to srcset. That okay?

3.1.2 Updating the List of Source Sets

When asked to update the list of source sets for a given picture element picture, user agents must do the following:

  1. Initially set picture’s list of source sets to the empty list.
  2. Iterate through picture’s child elements, doing the following for each child child:
    1. If child is an img element, exit this sub-algorithm.
    2. If child is not a source element, continue to the next child. Otherwise, child is a source element.
    3. If child does not have a src attribute, continue to the next child.
    4. Parse child’s src attribute and let the returned source set be source set.
    5. If source set has zero image sources, continue to the next child.
    6. If child has a media attribute, and its value is a valid media query which evaluates to true, attach the media query to source set. If its value is not a valid media query, or is a valid media query that evaluates to false, continue to the next child.
    7. If child has a sizes attribute, parse its sizes attribute and let source set’s source size list be the returned value. Otherwise, let source set’s source size list be an empty source size list.
    8. If child has a type attribute, and its value is an unknown or unsupported MIME type, continue to the next child.
    9. Normalize the source densities of source set.
    10. Append source set to picture’s list of source sets.

I’d like to allow individual sources to specify a type as well with a type() function, overriding the default type specified by the type attribute, but I’m keeping things simple for now.

3.1.3 Parsing a src Attribute

When asked to parse a src attribute from an element, parse the value of the element’s src attribute with the following grammar:

  <image-source-list> = <image-source>#
  <image-source> = <url> [ <resolution> | <source-width> ]?

The above grammar must be interpreted per the grammar definition in [CSS3VAL]. For the purposes of the above grammar, the <url> production is simply any sequence of non-whitespace characters that does not end in a comma. The <source-width> production is a dimension with a unit of w. All other terminal productions are defined as per CSS.

If the value does not parse successfully according to the above grammar, return an empty source set.

Otherwise, let source set initially be an empty source set. For each <image-source> parsed, do the following:

  1. Let source be a fresh image source.
  2. Set source’s URL to the parsed <url>.
  3. If a <resolution> was parsed, set source’s resolution descriptor to the <resolution>’s value.
  4. If a <source-width> was parsed, set source’s width descriptor to the <source-width>’s value.
  5. Append source to source set.

Then return source set.

3.1.4 Parsing a sizes Attribute

When asked to parse a sizes attribute from an element, parse the value of the element’s sizes attribute with the following grammar:

  <source-size-list> = <source-size>#?
  <source-size> = <media-query>? <length>

The above grammar must be interpreted per the grammar definition in [CSS3VAL].

If the value does not parse successfully according to the above grammar, return an empty source size list.

Otherwise, let source size list initially be an emtpy source size list. For each <source-size> parsed, do the following:

  1. If the parsed <source-size> does not contain a <media-query>, set source size list’s default size to the parsed <length>. This can be set multiple times; last wins. Continue to the next <source-size>.
  2. If the <media-query> evaluates to false, continue to the next <source-size>.
  3. Otherwise, create a new pair of the parsed <media-query> and the parsed <length>, and append it to source size list.

3.1.5 Normalizing the Source Densities

An image source can have a density descriptor, a width descriptor, or no descriptor at all accompanying its URL. Normalizing a source set gives every image source a density descriptor.

When asked to normalize the source densities of a source set source set, user agents must do the following:

  1. Find the effective size from source set’s source size list, and let the result be effective size.
  2. For each image source in source set’s source size list:
    1. If the image source has a density descriptor, continue to the next image source.
    2. Otherwise, if the image source has a size descriptor, replace the size descriptor with a density descriptor with a value of size descriptor / effective size and a unit of x.
    3. Otherwise, give the image source a density descriptor of 1x.

3.1.6 Finding the Effective Size

When asked to find the effective size from a source size list list, user agents must do the following:

  1. If list contains any <media-query>/<length> pairs, find the first <media-query>, in pair order, that evaluates to true. If one was successfully found, return the <length> from its pair.
  2. Otherwise, if list has a default size, return that.
  3. Otherwise, return 300px.

3.2 Interaction with the Preload Scanner

Some UAs utilize a “preload scanner”, which is a simplified parser that runs ahead of the main HTML parser during the initial load of the page, looking for URLs that it can begin loading as quickly as possible.

The definition of the picture element is compatible with a preload scanner, at least for some media queries.

If a UA uses a preload scanner, it must recognize when a an img element is a child of a picture, and use the full algorithm to select an image source to determine which URL to pre-load, with the following caveats:

3.3 HTMLPictureElement interface

interface HTMLPictureElement {
  };

We could maybe add some more things here, like a list of the relevant source elements and the active img element. Readonly? I dunno.

4 Changes to the source Element

When a source element is a child of picture element, the syntax of its src attribute is changed. Instead of being a URL, it must instead match the following grammar:

  <source-src> = <image-source>#

Additionally, the source element gains a sizes attribute, which contains a set of intrinsic sizes for the sources it provides. The sizes attribute is reflected by the sizes attribute on the element’s DOM interface.

partial interface HTMLSourceElement {
    attribute DOMString sizes;
  };

5 Acknowledgements

A complete list of participants of the Responsive Images Community Group is available at the W3C Community Group Website.

Contributions also from: David Newton, Ilya Grigorik and Leon de Rijke. Special thanks to Adrian Bateman for providing the group with guidance.

Conformance

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

References

Normative References

[CSS3VAL]
Håkon Wium Lie; Tab Atkins; Elika J. Etemad. CSS Values and Units Module Level 3. 30 July 2013. W3C Candidate Recommendation. (Work in progress.) URL: http://www.w3.org/TR/2013/CR-css3-values-20130730/
[HTML]
Ian Hickson. HTML. Living Standard. URL: http://whatwg.org/html
[MEDIAQ]
Florian Rivoal. Media Queries. 19 June 2012. W3C Recommendation. URL: http://www.w3.org/TR/2012/REC-css3-mediaqueries-20120619/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. URL: http://www.ietf.org/rfc/rfc2119.txt
[respimg-usecases]
Marcos Cáceres; et al. Use Cases and Requirements for Standardizing Responsive Images. NOTE. URL: http://www.w3.org/TR/respimg-usecases/

Informative References

Index

Property index

No properties defined.

Issues Index

Need a bunch more examples + explanation.
This is meant to be the HTML integration point.
make the img throw an error, however that’s done.
Exit this algorithm.
Load the url of selected source, etc.
This just selects a single image and then sticks with it, unlike CSS’s image(), but similar to srcset. That okay?
I’d like to allow individual sources to specify a type as well with a type() function, overriding the default type specified by the type attribute, but I’m keeping things simple for now.
We could maybe add some more things here, like a list of the relevant source elements and the active img element. Readonly? I dunno.