Technical

Responsive Images for Busy People: Srcset & Sizes

by on 30th September 2015

This guide won’t regale you with the cool theory behind responsive images, because for now, you’re just testing the waters. It won’t lecture you on the potential benefits to site speed, because there are better resources out there. And it won’t dwell on the pitfalls, quirks, or brain-bending complexities of the modern implementation, because you’re a busy person and will study these later.

Instead, we’re going to look at a single real-life example of efficient image scaling using the new srcset and sizes attributes. These should not be used for art direction – for this, you’ll want to use picture and source media. Instead, we’re strictly concerned with ensuring that the user’s browser loads the most appropriately-sized version of our image based on the size of the viewport. We want the browser to be able to pick a source file before parsing or rendering CSS and JavaScript. To do this, we’ll need to supply it with:

  • a list of image source files, plus their widths in pixels
  • hints about the size at which the image will be rendered on the page

A Live Example

We’ll dive right in with a live example, and then break down how it works. For the sake of being topical (and because NASA / JPL kindly release their images into the public domain), we’ll go with the Curiosity Rover’s selfie on Mars. The three image source files have been watermarked for convenience.

See the Pen yYgLaQ by Tom Bennet (@tombennet) on CodePen.

Take a peek at the HTML and CSS powering this example. What’s going on here?

The first thing to note is that the usual src and alt attributes are present and correct. Browsers which don’t support the new syntax will simply load the resource specified in the src as a fallback.

srcset

Next up, srcset. As you’ll see, this attribute contains a comma-separated list of image URLs; each one is followed by its width in pixels, specified using the w descriptor. ‘Why can’t we specify heights too?’, I hear you ask. Well, most images in responsive environments are constrained by their widths, not their heights, so dealing solely in widths keeps things simple. This situation may change in the future, but not today.

So, our browser now knows which resources it can choose from. Splendid. There is, however, a problem: the browser doesn’t know the size at which the image will be rendered on the page until it has downloaded and parsed all the relevant CSS and JavaScript files. Relaying this information to the browser before it starts processing your page’s layout will enable it to start downloading the appropriate image file as soon as possible.

sizes

This is where sizes comes into play. This attribute is used to describe the various sizes at which the image will be rendered on the page. Much like srcset, it takes a comma-separated list, but in this case we supply a list of CSS lengths paired with media conditions, which is then followed by a default length. This is easier to understand when you’ve got a simple example translated into English, so here goes…

sizes="(min-width: 40em) 33.3vw, 100vw"

This says: “If the viewport is wider than 40em, then this image will take up one third of the viewport. Otherwise, it will take up the full-width (100%) of the viewport.”

We’re pairing media conditions with CSS lengths, thereby giving the browser a clue as to the breakpoints it will encounter in the CSS. Note that more than one pair can be provided. The browser will iterate through your list of media conditions until it finds one that matches, and will then use the paired length as the image’s rendered width. If none match, it will use the last length in your list (the one without a paired query) as a default. Here’s the syntax:

sizes="
[media condition] [length],
[media condition] [length],
[media condition] [length],
[default length]"

Our browser now has all the information it needs to make a decision; it knows the widths of the source files, and the size at which the image will be rendered on our page.

calc

Why, then, is our Martian example slightly more complex? What is calc doing there?

On the Red Planet, as on Earth, determining the size of a single element can be complex in a responsive environment.

Thankfully, we can include the excellent and widely-supported CSS calc function to describe a relative length as mathematical expression. In our example, we’ve used calc(66.6vw - 4em) to express the length: “Two thirds of the viewport width, minus 4ems.” Sure enough, head into the CSS, and you’ll see rules that set our image width at 66.6% with 2em padding on either side.

Final Thoughts

A few pointers for those of you frantically resizing and refreshing the CodePen to try and change the watermark: the spec is fairly flexible, and allows the browser to make decisions based on both your markup and on other relevant factors. These can include the user’s connection, preferences, whether or not a larger asset is already cached, and so on. Something to bear in mind.

If this quick primer has tickled your fancy, be sure to check out the excellent resources below for a comprehensive introduction. Happy coding!

Resources:

Like this? Sign up to read more

Responses

  1. Thanks for the quick overview! The one thing I’m wondering is, was there a reason for using vw over % in your HTML whereas in your CSS you used %’s?

  2. Hi Benjamin.
    The length provided in the sizes attribute can be absolute (ems, px) or relative (vw, %). If you opt for a relative length, it must be relative to the viewport and not its parent container, irrespective of the unit. For this reason, I’ve simply used vw – it serves as a useful reminder of this fact. In CSS, on the other hand, when an element’s width is defined as a percentage it will be relative to that element’s container. In this case it makes little difference, since the image’s only parent is the body, but in practice you often have many nested elements each defined as a percentage of their parents, plus margins and paddings, etc. It’s in complex layouts such as these that the calc function becomes especially useful. For this reason, I’ve used % in the CSS.
    Hope that helps. Thanks for your comment!
    Tom

  3. Thanks for that Tom, I was wondering how the widths of nested elements using percentages were calculated. I get the feeling that you have just saved me a world of pain. :)

  4. Helpful resource! Thanks for sharing! Responsive images is what I am aiming now for my website. I am looking forward to see the full write of the CSS and HTML codes.

Comments are closed.