<picture> Picture

Holds several image sources and lets the browser choose one.

<picture> wraps zero or more <source> elements and then one <img>. The browser takes the first source whose media or type matches. If none does, the img is used.

Two jobs suit it: art direction, such as a tighter crop on phones, and serving AVIF or WebP with a JPEG fallback. The img cannot be left out. It is the element that displays, and its alt applies to whichever source wins. If all you need is size switching, srcset on the img does that alone.

The picture element definition (opens in a new tab) explains how the first matching source is chosen. The img element inside does the rendering.

Syntax

<picture>
  <source srcset="photo.avif" type="image/avif">
  <img src="photo.jpg" alt="Description">
</picture>

When to use it

There are two reasons to use <picture>. One is art direction. A wide panoramic banner turns into a thin strip on a phone, so small screens get a tighter, taller crop. The other is format choice: AVIF or WebP for browsers that understand them, JPEG or PNG for the rest, and no script involved.

Need the same image at several resolutions and nothing more? Then img with srcset and sizes is simpler, and the browser makes the call. For a decorative image, a CSS background with image-set() does much the same from the stylesheet.

Put sizes and styles on the inner img. picture is an inline wrapper and nothing more, and a width or border on it won't resize the image. The browser also stops at the first source that matches, so the most specific media query or the newest format goes first.

Live example

Edit the code and watch the preview.

<picture>
  <source media="(min-width: 700px)" srcset="mountains.svg">
  <img src="cat.svg" alt="Illustration that changes with screen width" width="400" height="300">
</picture>
<p>Resize the preview: wide screens show mountains, narrow ones a cat.</p>

More examples

Skipping unknown formats

A real page would list photo.avif and photo.webp. This one uses a made-up format to show the idea. The browser skips a type it doesn't support, downloads nothing, and moves on to the next source.

<picture>
  <source srcset="pancakes.future" type="image/x-future-format">
  <source srcset="pancakes.svg" type="image/svg+xml">
  <img src="pancakes.svg" alt="A stack of pancakes with berries" width="400" height="300">
</picture>

A crop for each orientation

A portrait screen gets a square close-up, a screen held sideways gets the wide scene. Every source carries its own width and height, and the browser reserves the right space for whichever image it picks.

<picture>
  <source media="(orientation: portrait)" srcset="avatar.svg" width="200" height="200">
  <img src="mountains.svg" alt="Header illustration" width="800" height="400" style="max-width:100%;height:auto">
</picture>

Tip: The last child of picture is an img, with alt text.

Browser support

All current browsers support picture. Very old ones ignore it and still show the inner img, so you lose nothing by using it. Width and height on a source inside picture came later, and current major browsers handle them now. Details are in the picture element support table (opens in a new tab).

Accessibility

Whichever source the browser picks, the alt text comes from the inner img, so every source should show the same content. What a text alternative has to cover is set out in the W3C note Understanding Non-text Content (opens in a new tab).

Common mistakes

Wrong

<picture>
  <source srcset="a.avif" type="image/avif">
</picture>

Right

<picture>
  <source srcset="a.avif" type="image/avif">
  <img src="a.jpg" alt="Sunset over the bay">
</picture>

No img means nothing shows up. The img also carries the alt text.

Frequently asked questions

What is the difference between picture and img srcset?

Use srcset and sizes on a plain <img> when you have one image at several resolutions and are happy for the browser to choose. Use <picture> when you want control, for example a different crop on small screens (art direction) or AVIF and WebP with a fallback. With picture, the browser has to use the source you specify. Can I use (opens in a new tab) tracks browser support for picture.

Does the picture element need an img inside?

Yes. A <picture> needs one <img> as its last child, after any <source> elements. The img does the rendering, and the sources only decide which file it loads. So the alt, width, height and loading attributes go on the img. On picture or source they do nothing.

Related media elements