Comm 333 Web Design II

Skip to navigation

Responsive Images in HTML

While we can use CSS media queries to adjust our CSS background images, images placed with the HTML img element require slightly different strategies.

We are concerned with two primary cases here: resolution switching and art direction.

Resolution Switching

In this case we are interested in making sure that the most appropriately sized image is used on our divice, based on a combination of:

  • Pixel Density
  • Image width

For this, we use a combination of the srcset and size attributes on our img element.

Pixel Density

To account for screens of varying pixel densities, we use the srcset attribute.

Assume we have this image of trees that we want to show in a 500px wide slot on our web page. We'll use the regular img tag with the appropriate alt text.

<img src="images/trees.jpg" alt="Trees in winter">
Trees in winter

Our 1x image size in this case is 500x333px. We'll need to generate images for each of the other pixel densities that we choose to support. In this case we'll optimize for four resolutions: 1x, 1.5x, 2x, 3x.

After generating our images and optimizing them, we end up with the following files and pixel dimensions:

  • trees.jpg [500x333]
  • trees@1.5x.jpg [750x500]
  • trees@2x.jpg [1000x666]
  • trees@3x.jpg [1500x999]

We modify our original img element to include the srcset attibute, which will specify which file to use for each resolution.

<img src="images/trees.jpg" alt="Trees in winter"
     srcset="images/trees.jpg,
             images/trees@1.5x.jpg 1.5x,
             images/trees@2x.jpg 2x,
             images/trees@3x.jpg 3x">

I've aligned the attributes to make it easier to read.

  • Each srcset option follows this format:
    • an image path
    • a space
    • the resolution
    • a comma
  • the resolution on the first option is omitted. When the resolution is omitted, 1x is assumed
  • the last option does not have a comma

Note that the src and alt attributes are still included. All images need alt attributes for accessibility. The src attribute remains as a fallback for older browsers that don't understand srcset. They'll just ignore the srcset attribute and load the image as usual.

For help with testing this in a browser, see Browser Testing Responsive Images.

Image Width

Specifying an exact pixel density works well when you know what size you want your image to be. However, when our pages are responsive, we often don't know the exact pixel width our images will be.

Instead of specifying the pixel density in our srcset attributes, we can specify a list of images to use specific widths.

<img src="images/snowdogs-400.jpg" alt="Cute snow dogs"
     srcset="images/snowdogs-400.jpg 400w,
             images/snowdogs-800.jpg 800w,
             images/snowdogs-1000.jpg 1000w,
             images/snowdogs-1400.jpg 1400w,
             images/snowdogs-2800.jpg 2800w">
  • Each srcset option follows this format:
    • an image path
    • a space
    • the target width: a pixel dimension followed by a 'w'
    • a comma
  • the last option does not have a comma
  • In this case we're using a suffix on our filenames to indicate the image width of the file. This is not necessary, but makes it easier.

When specifying the target width, the srcset attribute works in conjunction with the sizes attribute. The sizes attribute is essentially a mini media query. In its simplest form, we can use one value of 100vm, which is the default.

This will cause the image to be sized at 100vh (the whole page width). This size will be used by the browser to calculate which image is actually used.

<img src="images/snowdogs-400.jpg" alt="Cute snow dogs"
     sizes="100vw"
     srcset="images/snowdogs-400.jpg 400w,
             images/snowdogs-800.jpg 800w,
             images/snowdogs-1000.jpg 1000w,
             images/snowdogs-1400.jpg 1400w,
             images/snowdogs-2800.jpg 2800w">

Changing the sizes attribute value dramatically changes the math done by the browser. If the sizes attribute is set to 50vh, the image will only space half of the viewport width. Because of this, the browser will calculate which pixel width picture to load based on the width of 50vw.

<img src="images/snowdogs-400.jpg" alt="Cute snow dogs"
     sizes="50vw"
     srcset="images/snowdogs-400.jpg 400w,
             images/snowdogs-800.jpg 800w,
             images/snowdogs-1000.jpg 1000w,
             images/snowdogs-1400.jpg 1400w,
             images/snowdogs-2800.jpg 2800w">

Even more sizes

In the previous two examples, we only listed one size. That works fine, but is not a typical use case for a responsive design. In the most common responsive design patterns, you end up using a multicolumn layout with some sort of column drop pattern.

Imagine you are targeting three layouts:

  • Large screen sizes where there will be 3 columns. Images will span one column.
  • Medium screen sizes where there will be 2 columns. Images will span one column.
  • Small screen sizes where there will only be a single column. Images will span the viewport width.

You can write your sizes attribute in the style of a media query to account for each of these cases.

<img src="images/snowdogs-400.jpg" alt="Cute snow dogs"
     sizes="(min-width: 1200px) 33vw, (min-width: 600px) 50vw, 100vw"
     srcset="images/snowdogs-400.jpg 400w,
             images/snowdogs-800.jpg 800w,
             images/snowdogs-1000.jpg 1000w,
             images/snowdogs-1400.jpg 1400w,
             images/snowdogs-2800.jpg 2800w">

Art Direction

The art direction use case exemplifies a totally different problem than simply swapping out different sized images. In some cases, the meaning of an image, or usability of a change might vary depending on the size it is rendered at. Sometimes, as a designer you made need to serve different croppings of an image at various sizes.

An example illustrates this best.

This image might work better with a slightly tighter vertical crop at the medium size. At the small size, the figure is too small and the mountains are lost. Perhaps we do a tight crop on just the figure.

In this case, we can use a different html element: picture

The picture element acts as a wrapper and must also include a few other elements around inside it:

  • One or more source elements, each with the following attributes:
    • media: takes a media query
    • srcset: the link to the image and an optional resolution or width argument
  • One img element with the fallback image src and alternate text

A basic example of the case above would end up looking like this:

<picture>
   <source media="(min-width: 1200px)" srcset="images/snow-large.jpg">
   <source media="(min-width: 700px)" srcset="images/snow-medium.jpg">
   <img src="images/snow-small.jpg" alt="Snow forever">
</picture>

The media attribute is used to declare media queries. If the media attribute in a source element evaluates to false, the element is ignored.

Again, the img element is used as a fallback. In this case we're also doubling that as the final case for the small size. At the smallest browser sizes, the first two source element will be skipped. The img element will apply.

Combine picture with various resolutions and widths

You can make your picture elements even more complicated by adding in either resolution or width options to the srcset attributes. If we wanted to use images for 1x and 2x resolutions for the above example, it would look like this:
<picture>
   <source media="(min-width: 1200px)" srcset="images/snow-large.jpg 1x, images/snow-large@2x.jpg 2x">
   <source media="(min-width: 700px)" srcset="images/snow-medium.jpg 1x, images/snow-medium@2x.jpg 2x">
   <img src="images/snow-small.jpg" alt="Snow forever">
</picture>

All of the different sizes and variations can get pretty complex. Focus on taking care of the more simple and common cases.

Further Reading