HTML <picture> Tag

By Jonathan Griffin. Editor, SEO Consultant, & Developer.

· 5 min read

Definition

The <picture> tag contains an <img> element along with zero or more <source> elements to offer different images depending on the user’s screen pixel density, viewport size, image format, and more.

Example

<picture>
<source 
    media="(min-width: 1400px)"
    srcset="https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_320/image/fired.jpg 320w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_800/image/fired.jpg 800w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_1200/image/fired.jpg 1200w"
    sizes="(min-width: 60rem) 35vw,
           (min-width: 40rem) 45vw,
           100vw">
  <source 
    media="(min-width: 1000px)"
    srcset="https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_320/image/thumbs-down.png 320w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_800/image/thumbs-down.png 800w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_1200/image/thumbs-down.png 1200w"
    sizes="(min-width: 60rem) 35vw,
           (min-width: 40rem) 45vw,
           100vw">
    <source 
    media="(min-width: 600px)"
    srcset="https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_320/image/thumbs-up-large.png 320w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_800/image/thumbs-up-large.png 800w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_1200/image/thumbs-up-large.png 1200w"
    sizes="(min-width: 60rem) 35vw,
           (min-width: 40rem) 45vw,
           100vw">
  <img src="https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_320/image/thumbs-up-large.png" 
    alt="Image description">
</picture>

Usage

  • The opening and closing tags are required.
  • The <picture> element must contain zero or more <source> elements, followed by one <img> element.
  • The <picture> element should be used for art-direction purposes. For instance, you may want to specify different images for landscape, or portrait orientations. Alternatively, you may want to show a cropped image for mobile users.
  • While the <picture> element is capable of displaying different images based on resolution or pixel density, if that is all you require, it is more simple to just use the <img> element, along with the srcset and sizes attributes.
  • You can also use the <picture> element for displaying partially support files. For example, you may have an webp image, but want to provide a backup image if that image cannot be loaded by an old browser. To do this, you can just stack <source> elements until it finds an image it can load. For example:
      <picture>
      <source type="image/webp" srcset="example.webp">
      <source type="image/svg+xml" srcset="example.svg"> 
      <img src="example.png" alt="Example showing partially supported image loading.">
    </picture>
      

Example Commentary

  1. Start with a default <img> element. This contains a regular <img> along with an alt attribute to provide a text-based decscription. Add size attributes, such as height and width.

    Once configured, the <picture> element will display an image, but it will only leave you with one image, no matter the size or pixel density of the user’s screen.

    <picture>
    <img src="img_orange_flowers.jpg" alt="Flowers" width="500" height="200">
    </picture>

  2. The next step is to add the srcset attribute. This can be added to the <img> element, or in the case of this example, a <source> element. Here, you add each of your different size images, and tell the browser how wide each of them is. The image should be the same, just different sizes. The browser will then use that information to display the most appropriate size image for the user.

    <picture>
    <source srcset="image-small.png 320w, image-medium.png 800w, image-large.png 1200w">
    <img src="image-small.png"
    alt="Image description">
    </picture>

  3. Now, let’s add the sizes attribute. Use this when you want your images to be a specific width at various viewport sizes. This is a separate concept to the real image widths set in the srcset attribute.

    It doesn’t tell the browser what image to load, it just gives more information to the browser so it can pick the best image. Essentially, you should not think of these as regular media queries. The browser will generate empty image containers based on your sizes attribute. Then it will then choose the best images from your srcset to fill them.

    <picture>
        <source srcset="https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_320/image/thumbs-up-large.png 320w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_800/image/thumbs-down.png 800w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_1200/image/fired.jpg 1200w"
        sizes="(min-width: 60rem) 35vw,
               (min-width: 40rem) 45vw,
               100vw">
        <img src="https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_320/image/thumbs-up-large.png" 
        alt="Image description">
        </picture>
      

  4. Finally, we come to the key functionality that the <picture> element is used for. By adding a media attribute, you can specify the image to be used at different media widths or orientations. The order of the <source> elements matters, so make sure you put the largest media queries last.

    <picture>
        <source 
        media="(min-width: 600px)"
        srcset="https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_320/image/thumbs-up-large.png 320w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_800/image/thumbs-up-large.png 800w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_1200/image/thumbs-up-large.png 1200w"
        sizes="(min-width: 60rem) 35vw,
               (min-width: 40rem) 45vw,
               100vw">
        <source 
        media="(min-width: 800px)"
        srcset="https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_320/image/thumbs-down.png 320w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_800/image/thumbs-down.png 800w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_1200/image/thumbs-down.png 1200w"
        sizes="(min-width: 60rem) 35vw,
               (min-width: 40rem) 45vw,
               100vw">
        <source 
        media="(min-width: 1200px)"
        srcset="https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_320/image/fired.jpg 320w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_800/image/fired.jpg 800w, https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_1200/image/fired.jpg 1200w"
        sizes="(min-width: 60rem) 35vw,
               (min-width: 40rem) 45vw,
               100vw">
        <img src="https://res.cloudinary.com/thewebmaster/image/upload/ar_16:9,c_fill,f_auto,g_auto,q_auto,w_320/image/thumbs-up-large.png" 
        alt="Demo showing the HTML picture element.">
    </picture>
      
    Adjust your browser width to see how the image below changes.

    Demo showing the HTML picture element.

  • There are other ways to configure the <picture> element.
    • For instance, instead of telling the browser how wide the image is in the srcset attribute, you can specify the pixel density. For example:
      <picture>
        <source srcset="image-hidpi.png 2x, image-higherdpi.png 4x">
        <img src="image-small.png"
      alt="Image description">
      </picture>
  • You will find more information on the <source> element here, including more details of the media, and sizes attributes.

Attributes

The <picture> element only supports the Global Attributes.

Best Practices

  • Use the CSS object-position property on the child <img> element to adjust the image’s position within the element’s frame.
  • Use the CSS object-fit property on the child <img> element to adjust how the image is resized within the element’s frame.
  • Note that assistive technology, such as screen readers, uses the alt attribute value in the <img> fallback. You should ensure this adequately describes the image.
  • There is a split opinion in the developer community over whether to use media and sizes attributes together. However, we believe they work together well.

Specification

Browser Support

Desktop

ChromeEdgeFirefoxIEOperaSafari
YesYesYesNoYesYes

Mobile

Android WebviewChrome AndroidFirefox AndroidOpera AndroidiOS SafariSamsung Internet
YesYesYesYesYesYes