Responsive images. What to use: img or picture?

Responsive images. What to use: img or picture?

The img and picture tags are designed for loading images. Each of them allows you to define a set of rules according to which the browser will choose which of the images to load. Let's take a look at the syntax and differences of these tags. First, you need to set the following meta tag:

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

This meta tag tells the browser to scale the device's screen size. So, for example, the screen dimensions of the iPhone X are 375x812 css pixels.

For testing, we will use the following image:

bears.jpg

img tag

The srcset attribute is designed for specifying all available image sizes and URLs for each one. You still need to specify the src tag. Its value will be used if all options from srcset do not match according to the specified rules.

The srcset attribute contains a comma-separated list of one or more strings indicating a set of image sources. Each line consists of:

  1. Image URL.
  2. Width descriptor.

Let's take an example:

<img
  src="bears-1920x1080.jpg"
  alt="bears"
  srcset="
    bears-480x270.jpg    480w,
    bears-960x540.jpg    960w,
    bears-1920x1080.jpg 1920w
  "
/>

The width of all available images is specified in pixels. For historical reasons, the symbol w is used to represent pixels. In this example, the srcset attribute contains three images that are 480, 960, and 1920 pixels wide, respectively. The browser will select an image based on the device's screen width and pixel density. If the screen width does not exceed 480 css pixels, then the following image will be selected:

  1. bears-480x270.jpg if the pixel density factor is 1.
  2. bears-960x540.jpg if the pixel density ratio is 2 (retina display).
  3. bears-1920x1080.jpg if the pixel density ratio is greater than 2.

Similarly, if the screen width is greater than 480 css pixels, but does not exceed 960 css pixels, then:

  1. bears-960x540.jpg if the pixel density factor is 1.
  2. bears-1920x1080.jpg if the pixel density factor is greater than or equal to 2.

In this case, the browser will assume that the image occupies the entire width of the screen. To override this behavior, the sizes attribute is intended, which contains a comma-separated list of one or more strings that indicate the maximum width the image can occupy at a given screen size. Each line consists of:

  1. Media query.
  2. Image width.

Let's take an example:

<img
  src="bears-1920x1080.jpg"
  alt="bears"
  sizes="(max-width: 600px) 480px, (max-width: 1200px) 960px, 100vw"
  srcset="
    bears-480x270.jpg    480w,
    bears-960x540.jpg    960w,
    bears-1920x1080.jpg 1920w
  "
/>

In this example, the browser will follow these rules when choosing an image source:

  1. If the width of the device screen is no more than 600 css pixels, then image on such screen occupies maximum of 480 css pixels in width.
  2. If the device screen width is in the range from 600 css pixels to 1200 css pixels, then the image on such a screen occupies a maximum of 960 css pixels in width.
  3. Otherwise, the browser will assume that the image can span the entire width of the screen.

You also need to take into account the pixel density coefficient. For example, if the device screen width is 550 css pixels, then the browser will select the following image:

  1. bears-480x270.jpg, if the pixel density coefficient is 1. Since the width of the device screen does not exceed 600 css-pixels, the image on such a screen occupies a maximum of 480 css-pixels in width.
  2. bears-960x540.jpg if the pixel density ratio is 2.
  3. bears-1920x1080.jpg if the pixel density ratio is greater than 2.

The sizes attribute should be specified if the image sizes are limited by css styles. If the sizes attribute is not specified, it defaults to 100vw (sizes = "100vw"), which means the browser will assume that the image can span the entire width of the screen.

picture tag

The picture tag serves as a container for one or more source tags and one img tag. The source tag represents the source of the image. It contains information about the format of the image and its dimensions, as well as the rules under which the browser must select this source. If all sources do not match, then the file specified in the src attribute of the img tag will be selected. If several sources are suitable at once, then the browser will select the first one in order.

The source tag has the sizes and srcset attributes. They work the same way as the corresponding attributes for the img tag. Let's take an example:

<picture>
  <source
    srcset="bears-480x270.jpg 480w, bears-960x540.jpg 960w, bears-1920x1080.jpg 1920w"
    sizes="(max-width: 600px) 480px, (max-width: 1200px) 960px, 100vw"
  />
  <img src="bears-1920x1080.jpg" alt="bears" />
</picture>

This example works the same as the second example using the img tag.

Difference between img and picture

The picture tag allows you to tell the browser to use different images depending on the screen size. This is achieved by using the media attribute of the source tag, which allows you to set the media query in which this source will be used. For example, on small screens, we want to use the cropped image cropped-bears.jpg, which contains the main part of the image:

bears_cropped_s.jpg

To do this, you need to specify several source tags and set the media attributes:

<picture>
  <source
    media="(max-width: 480px)"
    srcset="
      cropped-bears-480x270.jpg 480w,
      cropped-bears-960x540.jpg 960w
    "
  />
  <source
    media="(max-width: 960px)"
    srcset="bears-960x540.jpg 960w, bears-1920x1080.jpg 1920w"
  />
  <img src="bears-1920x1080.jpg" alt="bears" />
</picture>

In this example, if the device screen width does not exceed 480 css pixels, then the cropped image will be selected. You cannot achieve this result with the img tag, since the images cropped-bears-960x540.jpg and bears-960x540.jpg are the same size, but the image cropped-bears-960x540.jpg is intended for use on a device whose width does not exceed 480 css pixels and the pixel density ratio is 2, and the bears-960x540.jpg image is on a device whose width is from 480 to 960 css pixels and the pixel density ratio is 1.

Also, the picture tag allows you to specify various image formats such as webp and jpeg. To do this, set the type attribute to the source tag:

<picture>
  <source
    type="image/webp"
    media="(max-width: 480px)"
    srcset="
      cropped-bears-480x270.webp 480w,
      cropped-bears-960x540.webp 960w
    "
  />
  <source
    type="image/webp"
    media="(max-width: 960px)"
    srcset="bears-960x540.webp 960w, bears-1920x1080.webp 1920w"
  />
  <source
    type="image/jpeg"
    media="(max-width: 480px)"
    srcset="
      cropped-bears-480x270.jpg 480w,
      cropped-bears-960x540.jpg 960w
    "
  />
  <source
    type="image/jpeg"
    media="(max-width: 960px)"
    srcset="bears-960x540.jpg 960w, bears-1920x1080.jpg 1920w"
  />
  <img src="bears-1920x1080.jpg" alt="bears" />
</picture>

Sources with the least supported types should be placed at the top because the browser will pick the first matching source. In this example, the browser will select the webp image type if it supports it. Otherwise, the jpeg type will be selected.