Images with <picture> tag

Images with <picture> tag

The <picture> tag is a versatile HTML element that allows developers to provide different versions of an image to users based on their device size or resolution. By using the <source> tag to specify different versions of the same image, we're sure to serve only the most appropriate image, potentially reducing the amount of data that needs to be downloaded, leading to improved load times and less data usage. Plus, it's much better than trying to force a one-size-fits-all approach for images.

The <source> tag specifies multiple versions of the same image in different formats, sizes, or resolutions, and then the <picture> tag selects the appropriate version based on the device's specifications.

Basic example

<picture>
  <source srcset="example-desktop.jpg" media="(min-width: 768px)">
  <source srcset="example-mobile.jpg">
  <img src="example-default.jpg" alt="Example Image">
</picture>

Let's break this down: In this basic example, we have used the <picture> element to display different images depending on the device's screen size. The first <source> element specifies a higher-resolution image for devices with a screen width of 768 pixels or more, while the second <source> element specifies a lower-resolution image for all other devices. Finally, the <img> element is used as a fallback image, in case none of the <source> elements are matched.

A more advanced example

<picture>
  <!-- WebP image for supported browsers -->
  <source 
    type="image/webp" 
    media="(min-width: 768px)" 
    sizes="(max-width: 767px) 50vw, (min-width: 768px) 100vw"
    srcset="
    example-l.webp   800w,
    example-m.webp   500w
    "
    >
  <!-- Fallback to JPEG for unsupported browsers -->
  <source 
    media="(min-width: 768px)" 
    sizes="(max-width: 767px) 320px, (min-width: 768px) 800px"
    srcset="
    example-l.jpg  1x   800w,
    example-l_2x.jpg 2x  800w,
    example-m.jpg  1x   500w,
    example-m_2x.jpg 2x  500w
    "
    >
  <!-- Fallback to JPEG for devices with small screens -->
  <source 
    media="(max-width: 767px)" 
    sizes="(max-width: 767px) 320px"
    srcset="
    example-s.jpg  480w,
    example-xs.jpg 320w
    "
    >
  <!-- Fallback to the highest resolution for devices that don't support the picture element -->
  <img 
    src="example-l.jpg" 
    alt="example"
    sizes="(max-width: 767px) 320px, (min-width: 768px) 800px"
    >
</picture>

In this second example, we have used several advanced features available for the <picture> element. We have also specified the type of image as image/webp in the <source> elements to take advantage of the newer, more efficient image format (an article on this topic is on the way).

Choice process

  1. Check for browser support for the srcset attribute: The browser checks if it supports the srcset attribute, which is used to provide a list of image files with different resolutions and formats. If the srcset attribute is not supported, the browser will simply use the src attribute to load the image file.

  2. Check for type attribute compatibility : then the browser looks for the type attribute for each source element that specifies the MIME type of the image file. If it does not support the MIME type, it will not use that source file.

  3. Check for media attribute: specifies a media condition that must be true in order for the associated source element to be considered. It is defined like CSS media queries.

  4. Check for sizes attribute: it provides a size hint to the browser about the image dimensions at a certain screen width.

  5. Check for width attribute (descriptor: w): the width attribute specifies the width of the image file in pixels. The browser selects the source with a width that matches the layout viewport's width (as defined by CSS media queries). If multiple sources have the same width, the browser selects the first matching source.

  6. Check for pixel density (descriptors: 1x, 2x, 3x): If no sources match the width of the layout viewport, the browser checks for the pixel density of the screen. The browser determines the pixel density of the device (standard density, 2x density, 3x density) and selects the source element with the appropriate descriptor.

  7. Falls back to default src: If the browser doesn't find any image file that matches the type, width, and pixel density, It falls back to use the default src attribute, which is the source file specified by the last img element.

Final considerations

You might ask, "Why going through all of this trouble?" Well, by providing different versions of the image, we're reducing the amount of data that needs to be downloaded by our site visitors. This leads to faster load times and less bandwidth usage. The second example is honestly the most complex I can think of, but if you would give <picture> a try, even in its easier form is able to optimize quite a bit your document's performances.

So, to summarize, the <picture> tag is a helpful tool for web developers that provides users with fast-loading, high-quality images that are appropriate for their device. Additionally, the tag improves web accessibility by allowing screen readers to understand the context of the images, thereby creating a more inclusive environment for all users. By remembering these key points when working with <picture>, developers can improve the user experience on their website while also making the web a better place for eve