Introducing the <picture> element
The <picture>
element offers a declarative approach towards image resource
loading. Web developers will no longer need CSS or JavaScript hacks to handle
images in responsive designs. And users benefit from natively-optimized image
resource loading—especially important for users on slower mobile internet
connections.
Alongside the newer srcset
and sizes
attributes
recently added to <img>
, the
<picture>
element gives web developers more flexibility in specifying image
resources. Write clear HTML markup and let the browser do the work of detecting
any of the following scenarios, alone or in combination, to support responsive
designs and improve web page load times:
- Art direction-based selection
- Is this a mobile device held in a portrait orientation or a wide desktop monitor? Load an image that is optimized for the given screen dimensions.
- Device-pixel-ratio-based selection
- Does the device have a high DPI display? Load a higher resolution image.
- Viewport-based selection
- Is the image meant to always fill a fixed proportion of the viewport? Load images relative to the viewport.
- Image format-based selection
- Can the browser support additional image file types that offer performance boosts such as smaller file sizes? Load an alternative image file such as WebP.
Use for art direction
The most common use of the <picture>
element will be for "art direction" in
responsive designs. Instead of having one image that is scaled up or down based
on the viewport width, multiple images can be designed to more appropriately
fill the browser viewport.
Improve resource loading performance
When using <picture>
, or <img>
with the srcset
and sizes
attribute, the browser
will only download the image explicitly stated for the matching scenario. This
native implementation is compatible with HTML parsers and can take advantage of
the browser's image caching and preloading abilities.
View a live demo
It's a fact that the Internet was created to host cat images. Using <picture>
we
can emulate the amazing ability of cats to adjust to the space given to them no
matter how small or large.
Open the demo in a new tab with Chrome 38 or higher. Resize the viewport to see the cat in action.
As a starting point, this demo only shows off the bare minimum of features that
<picture>
has to offer. Let's dig into the syntax now.
The <picture> syntax
The following HTML and CSS snippet is everything that was used to implement the demo:
<style> img {display: block; margin: 0 auto;} </style> <picture> <source media="(min-width: 650px)" srcset="images/kitten-stretching.png"> <source media="(min-width: 465px)" srcset="images/kitten-sitting.png"> <img src="images/kitten-curled.png" alt="a cute kitten"> </picture>
Note how there is no JavaScript involved and no-third party libraries. The CSS
<style>
block is used only to style the image element and does not contain media
queries. The native implementation of the <picture>
element means that you can
declare your responsive images using only HTML.
Use with <source> elements
The <picture>
element has no unique attributes of its own. The magic happens
when <picture>
is used as a container for <source>
.
The <source>
element, which is used for loading media such as video and audio,
has been updated for image loading and these new attributes have been added:
- srcset (required)
-
Accepts a single image file path (e.g.
srcset="kitten.png"
).Or a comma-delimited list of image file paths with pixel density descriptors (e.g.
srcset="kitten.png, kitten@2X.png 2x"
) where a 1x descriptor is assumed when it is left off.Refer to Combine with pixel density descriptors for this in use.
- media (optional)
-
Accepts any valid media query that you would normally find in a CSS
@media
selector (e.g.media="(max-width: 30em)"
).Refer to the previous <picture> syntax example for this in use.
- sizes (optional)
-
Accepts a single width descriptor (e.g.
sizes="100vw"
) or a single media query with width descriptor (e.g.sizes="(max-width: 30em) 100vw"
).Or a comma-delimited list of media queries with a width descriptor (e.g.
sizes="(max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)"
) in which the last item in the list is used as the default.Refer to Combine with width descriptors for this in use.
- type (optional)
-
Accepts a supported MIME type (e.g.
type="image/webp"
ortype="image/vnd.ms-photo"
).Refer to Load alternative image file formats for this in use.
The browser will use the hints passed in as attribute values to load the most
appropriate image resource. The listing order of tags matter! The browser will
use the first <source>
element with a matching hint and ignore any following
<source>
tags.
Add a final <img> element
The <img>
element has also been updated to be used within
<picture>
as the fallback in case a browser does not support the picture element
or if no source element tags are matched. Using <img>
within
<picture>
is a requirement—if you forget it,
no images will show up.
Use <img>
to declare the default image to be used within a
<picture>
block. Place <img>
as the last child of
<picture>
since the browser will ignore any <source>
declarations that occur after an <img>
tag is found. The image tag is
also where you should attach alternative text using the image element's alt
attribute.
Combine with pixel density descriptors
Add support for high resolution displays using pixel density descriptors such as
1x, 1.5x, 2x, and 3x. The new srcset attribute
applies to both <img>
and <source>
elements.
The example below supports 1x, 1.5x, and 2x resolution screens:
<picture> <source media="(min-width: 650px)" srcset="images/kitten-stretching.png, images/kitten-stretching@1.5x.png 1.5x, images/kitten-stretching@2x.png 2x"> <source media="(min-width: 465px)" srcset="images/kitten-sitting.png, images/kitten-sitting@1.5x.png 1.5x images/kitten-sitting@2x.png 2x"> <img src="images/kitten-curled.png" srcset="images/kitten-curled@1.5x.png 1.5x, images/kitten-curled@2x.png 2x" alt="a cute kitten"> </picture>
Combine with width descriptors
Web Fundamentals covers the the new
sizes attribute
for the <img>
element indepth:
"When the final size of the image isn't known, it can be difficult to specify a density descriptor for the image sources. This is especially true for images that span a proportional width of the browser and are fluid, depending on the size of the browser.
Instead of supplying fixed image sizes and densities, the size of each supplied image can be specified by adding a width descriptor along with the size of the image element, allowing the browser to automatically calculate the effective pixel density and choose the best image to download."
Here's an example of using the sizes
attribute to set the proportion of an image
to always fill 80% of the viewport. It is combined with the srcset
attribute to
supply four versions of the same lighthouse photo in widths of 160px, 320px,
640px, and 1280px wide:
<img src="lighthouse-160.jpg" alt="lighthouse" sizes="80vw" srcset="lighthouse-160.jpg 160w, lighthouse-320.jpg 320w, lighthouse-640.jpg 640w, lighthouse-1280.jpg 1280w">
The browser will use these hints to choose the most appropriate image resource to serve up based on the viewport width and hardware display resolution:
With the addition of <picture>
, the sizes
attribute
can be applied to both <img>
and <source>
elements:
<picture> <source media="(min-width: 800px)" sizes="80vw" srcset="lighthouse-landscape-640.jpg 6400w, lighthouse-landscape-1280.jpg 1280w, lighthouse-landscape-2560.jpg 2560w"> <img src="lighthouse-160.jpg" alt="lighthouse" sizes="80vw" srcset="lighthouse-160.jpg 160w, lighthouse-320.jpg 320w, lighthouse-640.jpg 640w, lighthouse-1280.jpg 1280w"> </picture>
Building on the previous example, when the viewport is at 800px and above, the browser will serve up a landscape version of the lighthouse version instead:
Load alternative image file formats
The type
attribute of <source>
can be used to load alternative image file
formats that might not be supported in all browsers. For example, you can serve
an image in WebP format to browsers that
support it, while falling back to a JPEG on other browsers:
<picture> <source type="image/webp" srcset="images/butterfly.webp"> <img src="images/butterfly.jpg" alt="a butterfly"> </picture>
Additional code examples
Refer to Responsive Images: Use Cases and Documented Code Snippets to Get You Started on the Dev.Opera blog
for an exhaustive list of examples combining <picture>
and <img>
with the srcset
, media
, sizes
, and type
attributes.
Try it out today
The <picture>
element is
currently available Chrome 38.
Try it out with screen emulation in the Chrome DevTools.
If you have feedback on this new feature, drop us a line on the Chrome bug tracker.
If you're ready to start implementing <picture>
today but also want to add
support for responsive images in additional browsers, refer to the
<picture> element sample on Web Fundamentals
for using <picture>
with a polyfill.