DEV Community

Cover image for Understanding gatsby-image (Part 2): Responsive images 101
Alexa Steinbrück
Alexa Steinbrück

Posted on • Updated on

Understanding gatsby-image (Part 2): Responsive images 101

This is Part 2 of a three-part series covering the Gatsby plugin gatsby-image
Part 1: Graphql, generated files & generated markup
Part 2: Responsive images 101
Part 3: Controlling src-set, breakpoints and styling

In this post we’ll cover these things:

  • <picture> with <source> as child elements
  • <img> with srcset and sizes attribute
  • Using the browser devtools to find out which image files are really fetched by the browser

This is providing some helpful background knowledge to use gatsby-image, but it is not specific to gatsby-image.

How does the <picture> element work?

The <picture> element contains zero or more <source> elements and one <img> element.

From MDN:

“The browser will consider each child source element and choose the best match among them; if no matches are found or the browser doesn’t support the picture element, the URL of the img element’s src attribute is selected. The selected image is then presented in the space occupied by the img element.”
“The img element serves two purposes: it describes the size and other attributes of the image and its presentation, and it provides a fallback in case none of the offered source elements are able to provide a usable image.”

How does <img> with the srcset and sizes attribute work?

Checkout the following image markup. The srcset and sizes properties use a distinct notation:

<img 
 srcset=
  "my-img-280w.jpg 280w, 
   my-img-440w.jpg 440w, 
   my-img-800w.jpg 800w"
 sizes=
  "(max-width: 320px) 280px, 
   (max-width: 480px) 440px, 
   800px"
/>

"srcset defines the set of images we will allow the browser to choose between, and what size each image is." (MDN)

It reads as a string with comma-separated pairs of information: The file path followed by the width of the actual image as a number (without px) but with ‘w’ at the end.

What about the sizes attribute?

"sizes defines a set of media conditions (e.g. screen widths) and indicates what image size would be best to choose" (MDN)

It reads as a string with comma-separated pairs of information: a media condition in brackets, followed by the width of the slot the image will fill when the media condition is true.

“The last slot width has no media condition (this is the default that is chosen when none of the media conditions are true). The browser ignores everything after the first matching condition, so be careful how you order the media conditions.” (MDN)

Another option: <img> with srcset but without sizes

Check out this srcset attribute:

srcset=
 "my-img-300w.jpg 1x, 
  my-img-450w.jpg 1.5x, 
  my-img-600w.jpg 3x"

Instead of providing a width, we’re providing a so called x-descriptor that informs the browser to check the device pixel ratio (DPR) of the client’s monitor, and choose the right image.

This is useful for optimization for retina displays.

When should I use <picture> and when <img> & sourceset?

On first sight both ways seem to provide a solution for the same problem: Offering a choice of image files to let the browser choose from. The main guideline is:

1. Use <picture> for art direction and image-format-switching. 
2. Use <img> & sourceset for resolution-switching.

If you're wondering: "Art direction…? But I'm not an art director!" -  Read this definition of art direction within the domain of web development:

Art direction: The problem whereby you want to serve cropped images for different layouts — for example a landscape image showing a full scene for a desktop layout, and a portrait image showing the main subject zoomed in for a mobile layout.
(MDN)

What is meant by image-format-switching? Let's say we want to serve our images as the fast newer image format webp to our readers. But this format isn't supported yet by all browsers, so we have to provide a jpg image as a fallback. In this case we would use a <picture> element with two <source> elements: One for the webp and one for the jpg.

Testing: How to check which images are REALLY requested by the browser?

⚠️ Attention: It is not what you see inside the src of the <img > tag (but it can be)! Even more confusing: It doesn’t even have to be one from the srcSet array of the img element (but it can be)!

Two options to find out:

  • Open your browser’s developer tools Network Panel and checkout which file was fetched over the network

  • Open your browser’s developer tools “Inspector” or “Elements” panel: Select the img element and type into the Browser console: $0.currentSrc ($0 stands for the currently selected element)

👉 Continue with Part 3 of this series about gatsby-image: “Controlling sizes, breakpoints and styling”

Discussion (0)