The HTML <picture> element explained
Tags: webdev, beginners, html
Published: 2022-11-22 19:26:24

## Table of Contents

- [Why it's useful](#why-its-useful)
- [How it works](#how-it-works)
- [Implementation](#implementation)
- [Browser compatibility](#browser-compatibility)
- [Conclusion](#conclusion)
- [Resources](#resources)

In HTML, the `<picture>` element is used for displaying images based on resolution, device, and/or support for a particular image format.

---

## Why it's useful

There are several reasons why you might want to use the `<picture>` element over the regular `<img>` element:

### Format

There are a variety of image formats, such as WEBP, SVG, and AVIF that browsers may or may not support. By using the `<picture>` element, you can provide different alternative versions of an image.

### Bandwidth and Resolution

For smaller screens and devices, it isn't necessary to load a large image file with high resolutions. For example, having a 500 KB image file works well on a desktop computer, but it takes some time for a mobile device to load. With the `<picture>` element, it is possible to specify different images depending on different screen sizes, resulting in faster load speed and less bandwidth.

### Cropping

The `<picture>` element can also be used to crop images. More of this will be discussed in the [Implementation](#implementation) section.

---

## How it works

### `source`

The `<source>` element specifies different image sources. You can use as many `<source>` elements as you want.

It has the following attributes:

- `srcset` - the URL/path of the image to use in different situations. You can specify one or more image files here.
- `media` - a media query. If the query (or screen size) matches, the image will be used.
- `type` - the media type of the image, e.g. image/webp.

### `img`

The `<img>` element often acts as a fallback for browsers that don't support the `<picture>` element. It is recommended to use it as the last child of the `<picture>` element. Because If no matches are found, the `<img>` element is used to display the image.

> **Note:** It is required to use the `<img>` element, otherwise the `<picture>` element won't work.

---

## Implementation

Learn how to implement the `<picture>` element for the following use cases:

- Media queries
- Format
- Width and Pixel Density descriptor
- Cropping

### Media Queries

The different images for different screen sizes (with `media`):

```html
<picture>
  <source srcset="large.jpg" media="(min-width: 960px)" />
  <source srcset="medium.png" media="(min-width: 600px)" />
  <img src="small.png" alt="Image Description" />
</picture>
```

### Format

The same image in different formats:

```html
<picture>
  <source srcset="image.avif" type="image/avif" />
  <source srcset="image.webp" type="image/webp" />
  <img src="image.png" alt="Image Description" />
</picture>
```

> **Note:** The browser will pick the first format it recognizes and ignore the rest. Therefore, it might be a good idea to put high-quality images upfront and low-quality images at the end.

### Width and Pixel Density descriptor

The different images for different screen sizes

What we are telling in the below is that we want the browser to change the image automatically depending on the screen size. These values, "500w, 860w, and 1200w" represent the actual size or more specifically width of the image. The difference is that you provide values in `w` (width viewport) instead of `px` (pixels) units.

```html
<picture>
  <source srcset="small.png 500w" />
  <source srcset="medium.png 860w" />
  <source srcset="large.jpg 1200w" />
  <img src="small.png" alt="Image Description" />
</picture>
```

Alternatively, a pixel density descriptor can be used as well. It defines the pixel density of the image. The value, represented in `x`, such as `2x` displays high-resolution images on high-density (DPI) screens.

### Cropping

If you have images, but need some adjustments with their sizes based on the screen, `width` and `height` can be implemented to crop images.

For example, narrow and tall images for mobile, but wide and short images for desktop browsers.

```html
<picture>
  <source
    srcset="large.jpg"
    media="(min-width: 960px)"
    width="1280" height="600"
  />
  <source
    srcset="medium.png"
    media="(min-width: 500px)"
    width="800" height="400"
  />
  <img 
    src="small.png" 
    alt="Image Description" 
    width="500" height="400" 
  />
</picture>
```

---

## Browser Compatibility

The picture element is well supported on almost all browsers (at 97.13%) except Internet Explorer and Opera Mini. As of June 15, 2022, support for Internet Explorer has officially ended. 

Moreover, Since the `<img>` element is used by browsers that do not support the `<picture>` element, there is no need to worry about the browser compatibility.

[![browser support for picture element](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o68zvyizh04rres6g3ph.png)](https://caniuse.com/?search=picture)

---

## Conclusion

The `<picture>` element is a great way to display images in different formats, resolutions, and sizes. It can be used to improve the performance of your website by reducing the bandwidth and load time while providing a better user experience.

Hopefully, this article has given you a good understanding of the `<picture>` element. If you have any questions or suggestions, feel free to leave a comment below. Thanks for reading!

---

## Resources

- [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture)
- [HTML5 Rocks](https://www.html5rocks.com/en/tutorials/responsive/picture-element/)
- [Can I use](https://caniuse.com/?search=picture)