Lost your password?
Don't have an account? Sign Up

How to Use HTML5 “picture” for Responsive Images

Images are notoriously one of the most challenging aspects of responsive web design. Today we’ll look at how the <picture> element, a solution to the problem of responsive images, can be used right now.

First, the Problem

The days of fixed-width, pixel perfect website design are well and truly behind us. In the present day of widescreen monitors, internet TVs, multiple sized tablets and smart phones our designs now have to cater for everything from 320px wide up to potentially as high as 7680px wide.

Along with this multi-resolution landscape comes a need for images to stretch or shrink to fit these wildly varying requirements. This can prove to be something of a problem given that, with the exception of vector graphics, the vast majority of images have specific pixel based widths that do not change.

So what do we do?

The Current, Most Common Solution

As a general rule, you’ll find the following in just about any responsive site’s CSS:

This code uses the max-width: 100%; setting to ensure images never go beyond the width of their parent container. If the parent container shrinks below the width of the image, the image will scale down along with it. The height: auto; setting ensures the images’ aspect ratio is preserved as this occurs.

One fluid image for all circumstances
One fluid image for all circumstances

It solves the problem in one respect, allowing us to display the same image under many different circumstances. But it doesn’t allow us to specify different images for differing circumstances. For example, it’s quite possible that the original image is impractically large (in terms of file size) for some users to download on their mobile network.

Tip: Take a look at What Does My Site Cost? by Tim Kadlec to get an idea of the real cost of mobile data for users all over the world.

“According to the July 1, 2019 run of HTTP Archive, the median site now weighs 1937kb.” – What Does My Site Cost?

A Better Solution: The Picture Tag

<picture> is a newer element and part of the HTML5 spec. 

It brings the process for placing responsive images up to speed with the way the <audio> and <video> elements work (though not exactly the same). It allows you to place multiple source tags, each specifying different image filenames along with the conditions under which they should be loaded.

The <picture> tag allows you to load an entirely different image depending on:

  • Media query results e.g. viewport height, width, orientation
  • Pixel density

This in turn means you can:

  • Load appropriately file sized images, making the best use of available bandwidth.
  • Load differently cropped images with different aspect ratios to suit layout changes at different widths (perfect for art direction).
  • Load higher resolution images for higher pixel density displays.
Different images served depending on the circumstances thanks to the picture tag
Different images served, depending on the circumstances, thanks to the picture tag

How Does <picture> Work?

The basic steps of working with the <picture> tag are:

  1. Create opening and closing <picture> </picture> tags.
  2. Within those tags, create a <source> element for each query you want to run.
  3. Add a media attribute containing your query on things like viewport height, width, orientation etc.
  4. Add a srcset attribute with the corresponding image filename to load.
  5. Add extra filenames to your srcset attribute if you want to provide for different pixel densities, e.g. Retina displays.
  6. Add a fallback <img> element.

Here’s a basic example which checks if the viewport is smaller than 768px, then if so loads a smaller image:

Here’s what it looks like in action (you’ll need to shrink and stretch the screen to see the image swap out at 768px:

You’ll notice that the syntax used in the media attribute is the same as you might be used to from creating CSS media queries. You can use the same checks, meaning you can query max-width, min-width, max-height, min-height, orientation and so on.

You can use these checks to do things like loading landscape or portrait versions of an image depending on device orientation, and you can still mix in size queries at the same time. For example:

The above code loads a smaller, landscape cropped version of the image on a smaller, landscape oriented device. It loads a larger version of the same image on a larger landscape oriented device. 

If the device is portrait oriented it loads a portrait cropped version, at small size on a small device or at large size on a large device.

If you want to provide different resolution versions of your images for higher density displays, you do so by adding extra filenames to the srcset attribute. For example, let’s look at our first snippet of code from above with handling for Retina’s 2x resolution added:

The media query is still evaluated first so you can control the dimensions your image will appear at on screen. Then the display’s pixel density will be checked and if higher densities are both supported and allowed by the user’s preferences, the higher density version of image will be loaded.

The Type Attribute

You can also use the type attribute within a <source> element to specify a MIME type for the image. For example: type="image/svg+xml". If the browser doesn’t like it, it will skip over that source and move to the next.

A Note on Accessibility

Screen readers will use the alt text supplied in the fallback <img> element for whichever image is displayed in the browser. Make sure, therefore, that the alt text represents all the images equally well!

Browser Support for <picture>

Browser support for the <picture> element is very solid nowadays, though like many other aspects of modern CSS and HTML Microsoft lean on the Edge browser, rather than IE, to fly the team colors.

Browser support for picture element

By using the fallback <img> tag within <picture> you’re still catering for anyone using a non-supporting browser.

More Information

  • Get full information on the <picture> element from responsiveimages.org.
  • Picturefill: the go-to polyfill for <picture> (which arguably isn’t really needed these days)

Try out <picture> in your project today and see what you think!

Source link


Leave a Comment

Your email address will not be published. Required fields are marked *