# Picturefill

A responsive image polyfill

Officially endorsed by the RICG

The `picture` element, `srcset` and `sizes` attributes, and associated features allow web developers to deliver an appropriate image to every user depending on a variety of conditions like screen size, viewport size, screen resolution, and more. Picturefill enables support for the `picture` element and associated features in browsers that do not yet support them, so you can start using them today!

Picturefill development is sponsored by and , and maintained by the Picturefill Team. Ongoing discussion of the project is conducted via Slack.

### Contributing, Bug Reports, and More information

For more information on the development of Picturefill and how you can file bugs or contribute fixes, check out the project on GitHub.

## Downloading Picturefill

### Picturefill Version 3.0.2 (Stable)

Version 3 is a full rewrite of the Picturefill codebase, featuring optimized performance, better emulation of native behavior, and parsers that adhere much more closely to the specification. It also handles many of the quirks, shortcomings, and edge cases related to first-generation native implementations.

Feedback on this release is highly welcomed—if you encounter any problems, please file an issue on GitHub.

- picturefill.js

  (development version, unminified code)

- picturefill.min.js

  (production version, minified code)

### Picturefill Version 2.3.1

Picturefill 2 is a lightweight polyfill that may not perfectly match native responsive images behavior. Please note however that because of a recently-fixed bug, you should absolutely not be using any version of Picturefill prior to 2.3.1. If you are, please update immediately. These downloads include the matchMedia polyfill for browsers that need it (like IE9).

- picturefill.js

  (development version, unminified code)

- picturefill.min.js

  (production version, minified code)

## Getting Started with Picturefill

To start using Picturefill download one of the files listed above and reference it from the `head` section of your HTML document with the following code:

    <script src="picturefill.js"></script>

To allow your page to load more efficiently, we'd recommend adding an `async` attribute to that `script` tag as well. This tells the browser that it can load picturefill asynchronously, without waiting for it to finish before loading the rest of the document. If you add this attribute, you'll need to add a line of script before the `script` tag as well to allow older browsers to recognize `picture` elements if it encounters them in the page before picturefill has finished loading.

Recommended Usage:

    <head>
      <script>
        // Picture element HTML5 shiv
        document.createElement( "picture" );
      </script>
      <script src="picturefill.js" async></script>
    </head>

Note that if you are already including a recent version of the HTML5 Shiv (sometimes packaged with Modernizr), you may not need this line as it is included there as well. Also, more advanced users may not need this may choose to load Picturefill dynamically using a script loader like Require.js, (AMD and CommonJS support is included in the script).

## Markup Patterns

Once you've included picturefill.js, you can start adding responsive image elements to your site! Picturefill adds support for the the entire suite of responsive image solutions, including the `picture` element and new `img` element attributes.

There are a number of different use cases addressed by some combination of features from the responsive images specification—here are some of the most common ones:

### Using the `srcset` attribute

The `srcset` attribute (without `sizes`) is used to serve larger—but otherwise identical—image sources to high resolution displays only.

    <img srcset="examples/images/image-384.jpg 1x, examples/images/image-768.jpg 2x" alt="…">

Here's how that renders on your display:

If the intrinsic dimension plugin is installed: The `2x` source will be automatically scaled down by 2 — so that the image will occupy the same space in your layout as the `1x`, but the `2x` source will be displayed at double the pixel density. This only applies to the natural size of the `img`—resizing the image via CSS or with the `width` content attribute will behave as expected.

Modern browsers that support `srcset` natively may select a cached file that meets the minimum media condition, even if it is “overkill” for the current media condition. For example, a `2x` file may be shown on a `1x` device, if that `2x` file is already in the cache—there’d be no reason to make an additional request when the user will see no discernable difference, after all. This is typically encountered only on sites with multiple versions of the same image displayed in multiple elements at different sizes (like our demo page). The occasional selection of "oversize" resources—depending on the cache—is currently an expected behavior in native implementations and you may encounter it during testing.

Eventually `srcset` will be extended to allow the browser to override requests for higher-resolution options based on a bandwidth limitations or a user preference (see #9 in the Responsive Images Use Cases and Requirements).

### Using the `srcset` & `sizes` attributes

The `srcset` and `sizes` syntaxes are used to provide the browser with a list of image sources that are identical apart from their size (same aspect ratio, same focal point) and how they’ll be displayed, then allow the browser to choose the source best for the user’s current viewport size, display density, and the size of that image in the page layout.

    <img
      sizes="(min-width: 40em) 80vw, 100vw"
      srcset="examples/images/medium.jpg 375w,
              examples/images/large.jpg 480w,
              examples/images/extralarge.jpg 768w"
      alt="…">

Here's how that renders on your display at your current viewport size:

Standalone `srcset` and `sizes` demo

The `sizes` syntax is used to define the spaces your image will occupy in your layout. `srcset` then defines a list of images and their inherent widths. This allows the browser to choose the smallest appropriate source for the size available in that part of the layout, rather than the viewport size alone.

It's beyond the scope of this guide to get into much detail about how to use the new `srcset` & `sizes` attributes so we’d highly recommend reading the following post by Eric Portis: Srcset and Sizes. Keep in mind that the same caching behavior is applied to this usage of `srcset`, as well.

### Using the `picture` element

The `picture` element is used when you need explicit control over which source is shown at set viewport sizes.

The `picture` element requires a little more markup than the example above, but it allows you to use features like CSS3 Media Queries to pair image source with varying sizes, zoom levels, and aspect ratios with the layout conditions in your designs. It should not, however, be used to serve radically different image sources—all sources must be described by the `alt` attribute of the inner `img`.

    <picture>
      <source srcset="examples/images/extralarge.jpg" media="(min-width: 1000px)">
      <source srcset="examples/images/art-large.jpg" media="(min-width: 800px)">
      <img srcset="examples/images/art-medium.jpg" alt="…">
    </picture>

Here's how that renders at your current viewport size:

Standalone `picture` demo

Your `picture` element should contain a series of `source` elements followed by an `img` element. Each `source` element must have a `srcset` attribute specifying one or more image url sources (which can use expanded srcset syntax if desired for resolution switching), and the `img` element should have a srcset attribute for fallback purposes as well (some browsers like Android 2.3's won't see the `source` elements). Additionally, you may add a `media` attribute containing CSS3 Media Queries, and/or a `sizes` attribute to pair with `srcset`.

The first `source` with a `media` attribute that matches the user’s context will determine the src of the `img` element at the end, so you’ll want to present larger options first when using `min-width` media queries (like in the examples below), and larger options last when using `max-width` media queries. Since these image sources are meant to align with layout breakpoints, `srcset`’s caching behavior and the potential for a bandwidth or user preference override do not apply here.

### Supporting Picture in Internet Explorer 9

While most versions of IE (even older ones!) are supported well, IE9 has a little conflict to work around. To support IE9, you will need to wrap a `video` element wrapper around the source elements in your `picture` tag. You can do this using conditional comments, like so:

    <picture>
      <!--[if IE 9]><video style="display: none;"><![endif]-->
      <source srcset="examples/images/extralarge.jpg" media="(min-width: 1000px)">
      <source srcset="examples/images/large.jpg" media="(min-width: 800px)">
      <!--[if IE 9]></video><![endif]-->
      <img srcset="examples/images/medium.jpg" alt="…">
    </picture>

### Preventing the Flash of Wrong Image™ on Safari

Sometimes when using picturefill in Safari, the wrong image may briefly load before the correct source had been chosen. We call this the Flash of Wrong Image™. The only way to prevent this is by removing the `src` and `srcset` on the fallback image. It's important to note, however, that this may cause the image from displaying on old android devices (2.3).

    <picture>
      <!--[if IE 9]><video style="display: none;"><![endif]-->
      <source srcset="examples/images/extralarge.jpg" media="(min-width: 1000px)">
      <source srcset="examples/images/large.jpg" media="(min-width: 800px)">
      <!--[if IE 9]></video><![endif]-->
      <img alt="…">
    </picture>

### `media` and `srcset` syntax:

The `1x`/`2x` syntax can be used within `source` element `srcset` attributes as a shorthand for more complex resolution media queries.

    <picture>
      <source srcset="examples/images/large.jpg, examples/images/extralarge.jpg 2x" media="(min-width: 800px)">
      <img srcset="examples/images/small.jpg, examples/images/medium.jpg 2x" alt="…">
    </picture>

Standalone extended `picture` demo

### The `type` attribute in `picture`

The `types` attribute is used to send an alternate image source format only to browsers that support that format, and a fallback source to browsers that do not. Unlike existing solutions, the `picture` element makes these negotiations using a single request.

Picturefill supports SVG and WebP as part of its core, but the following MIME types can be used via the “typesupport” plugin:

- `image/bmp`
- `image/xbmp`
- `image/jp2`
- `image/vnd.ms-photo`
- `video/vnd.mozilla.apng`

    <picture>
      <source srcset="examples/images/large.webp" type="image/webp">
      <img srcset="examples/images/large.jpg" alt="…">
    </picture>

Here's how that renders in your browser:

Standalone `type` attribute demo

## Picturefill JavaScript API

Under ordinary circumstances, you likely won't need to do more than include picturefill.js in your page, but in some situations you may want to run picturefill's function manually yourself, and there are a few options to keep in mind:

### The Picturefill function

Picturefill.js exposes a single global function: the `picturefill()` function. `picturefill()` is automatically called one or more times while a page is loading, and it also is triggered when the browser window is resized (or on orientation change). You can run the `picturefill()` function at any time in JavaScript yourself as well, which may be useful after making updates to the DOM, or when conditions relevant to your application change:

    picturefill();

### Picturefill function options

When running the `picturefill()` function, you can pass options specifying the following configuration options:

- Elements: An array of `img` elements you'd like picturefill to evaluate. The Default value for `options.elements` is all `img` elements in the page that have a `srcset` attribute or have a `picture` element as a direct parent.

      picturefill({
        elements: [ document.getElementById( "myImg" ) ]
      });

- Reevaluate: If you dynamically change the `srcset`, `sizes` attributes, or modify `source` elements, please use this reevaluate option and provide an array or array-like object of your mutated `img` elements. As an alternative the mutation plugin can be used.

      picturefill({
        reevaluate: true,
        elements: [ document.getElementById( "myImg" ) ]
      });

### Picturefill plugins/extensions

Picturefill core polyfills the core part of responsive images, including full support for `srcset`, `sizes` and `picture`/`source`.

Some aspects of the native feature are left out to provide a clean and lightweight polyfill. In case you need a specific behavior of the native implementation not included in picturefill core, just add the corresponding plugin. The best way is to merge all scripts together.

- intrinsic dimension: This extension adds support for intrinsic dimension behavior of responsive images. It's useful when you don't style your images with CSS.
- Mutation plugin: This plugin automatically detects any DOM mutation and polyfills new or changed responsive images automatically. It also adds support for responsive images IDL attributes/properties. If you have a highly dynamic website or a SPA you probably want to use this plugin. (This plugin does not work with IE8.)
- Type support: This plugin extends support for the `source[type]` attribute and detects JPG2000, APNG and JPEG XR support. If you want to use new image formats you probably want to use this plugin.
- OldIE (IE6/7): picturefill supports most browsers including IE8+. In case you need to support IE6/7, you can combine the oldIE plugin with jQuery to add support for these browsers.

### Source selection algorithm option

By default Picturefill attempts to mimic the resource selection algorithms current native implementations, but Picturefill 3 also includes an optional and experimental custom source selection algorithm. The `saveData` algorithm skews the resource selection algorithm toward smaller image candidates(`2x` on extremely high dppx devices (`3x` and up), to conserve bandwidth in situations where there may be little or no visual difference between sources.

To use `saveData`, create a `picturefillCFG` array that runs before picturefill:

    //generating the config array
    window.picturefillCFG = window.picturefillCFG || [];
    picturefillCFG.push([ "algorithm", "saveData" ]);

Developer feedback on this new algorithm is highly welcomed. We’d love to see some data around potential bandwidth savings, and this data may go on to inform native responsive image implementations in the future.

## Browser Support

Picturefill supports a broad range of browsers and devices, provided that you stick with the markup conventions documented above.

### Support caveats

Picturefill is tested broadly and works in a large number of browsers. That said, it does have some browser support considerations to keep in mind:

- Picturefill 3 includes a small shim that polyfills common media conditions for IE9 and earlier (`min-width`, `max-width`, `min-height`, and `max-height`). If you need old IE support for other media conditions, such as `orientation` or `aspect-ratio`, please additionally include the matchMedia polyfill.
- JS-Disabled Browsers only see alt text: When using the `picture` element, non-`picture` supporting browsers will only see `alt` attribute text as a fallback when JavaScript fails or is disabled. This is because any `noscript`-based workarounds (such as the one used in Picturefill version 1) will cause future browsers that support the `picture` element to show two images instead of one when JavaScript is off. Unfortunately, adding a `src` attribute with an external source to the `img` element in your `picture` element isn't a good workaround either, as any browser that exists today will fetch that `src` url even if it is not going to be used (which is wasteful), and an empty `src` can result in unexpected requests. For valid markup, the shortest possible value for `src` (without firing an `onerror` event or a potential request) is

      src="data:image/gif;base64,R0lGODlhAQABAAAAADs="

- Temporary extra HTTP Requests for `picture` usage in some browsers: In browsers that natively support `srcset` but do not yet support the `picture` element, users may experience a wasted HTTP request for each `picture` element on a page. This is because the browser's preparser will fetch one of the URLs listed in the `picture` element's child `img`'s `srcset` attribute as soon as possible during page load, before the JavaScript can evaluate the potential `picture` `source` elements for a better match. This problem will only affect browsers that have implemented `srcset` but not `picture`, which will hopefully be short-lived.
- Source element limitations: Browsers like Android 2.3 and Internet Explorer 9 can not see the `source` elements inside a `picture` element. For IE, the `video` tag workaround helps us avoid this problem, but Android will still have no access to `source` elements. Be sure to provide a `srcset` attribute on your enclosed `img` to ensure an image will show in this browser.
- Media attribute support requires native media query supportThe `picture` element (paired with picturefill) works best in browsers that support CSS3 media queries. Picturefill includes the matchMedia polyfill by default, which makes matchMedia work in media query-supporting browsers that don’t support `matchMedia`.