A guide to Responsive images with srcset blog post

A guide to Responsive images with srcset

Niels den Dekker

6 Feb, 2019

6 minutes read

High resolution images are something we all want. Whether it’s on a mobile phone, a desktop or a laptop – no one wants to look at a blurry image. There are multiple ways to achieve this, but today we’re going to look at a solution simple to achieve with HTML. Let’s have a look at the srcset attribute.

The srcset attribute gives you the option to specify multiple images and let the browser decide what the best image is.

Let’s start with something simple:

<img src="/photo-small.jpg">

This is a normal image include which can be viewed on a normal laptop or for example a MacBook with a retina display. To get a high resolution version on a retina display we’d have to use media queries in CSS.

This would be your HTML:

<div class="low-res">
  <img src="/photo-small.jpg">
</div>
<div class="high-res">
  <img src="/photo-large.jpg">
</div>

As we mentioned, we’d need some CSS magic to let the browser know – hey, this is what I want to use when a user is visiting the website on a retina display.

.high-res {
  display: none;
}

@media 
(-webkit-min-device-pixel-ratio: 2), 
(min-resolution: 192dpi) {
  .low-res {
    display: none;
  }

  .high-res {
    display: block;
  }
}

Now this is all super fancy, but there’s a much simpler way of doing this. And we can do it with pure HTML!

The srcset attribute

This is where our new srcset attribute comes in. We’re basically moving all our CSS rules over to just one simple line, which would look like this:

<img src="/photo.jpg" srcset="/[email protected] 2x">

Let’s start dissecting what I’ve just shown you to get a better understanding of what’s going on in our new srcset attribute.

Conventions

As you can see I’ve used a rather weird name for photo.jpg which I changed to [email protected]. This is simply our original file, but exported twice the size. That’s why I have postfixed it with @2x. We’ve used an example with just 1 specific image size in srcset, but there could be 4 for example – which we will get on to later!

Here’s a quick example of how I would manage my files in srcset and make sure they’re making sense for everyone else who’s also going to work with your images and HTML.

<img src="/photo.jpg" srcset="/[email protected] 2x, /[email protected] 1000w" />

Note: we’re using widths here because srcset only works based on width or pixel density (1x, 2x, etc). You can’t specify an image based on a certain height of the screen.

Browser calculations

Before we go into all the specifics about different ways to specify your image widths. Let’s have a look at how your browser actually picks the image.

Your browser attempts to calculate the best fit image based on the device width. For regular devices the ratio it is looking for is 1. If the device is considered “retina” then the browser will multiply the result by 2 to find the best image size.

Multiply what you might ask? We’ve got a set of images of 500px, 1250px and 2500px.

The device we’re using has a width of 1000px, now let’s look at the calculations the browser makes:

500 / 1000 = 0.5
1250 / 1000 = 1.25
2500 / 1000 = 2.5

As we mentioned earlier, on non-retina devices the browser will try and match a ratio of 1. This means for this device it will pick the image of 1250px as it’s the closest to 1.

A retina display has a ratio of 2. This is where our multiply comes in. The browser will look at 1.25 and go, this image will be too small and will lose quality. It will then multiply 1.25 by 2 and see if there’s anything available.

There’s a 2500px image with a ratio of 2.5 which matches what the browser is looking for so it will automatically load in that image for optimum result.

The srcset attribute

Now we’ve talked about conventions and how the browser picks the image, let’s have a look at how the srcset attribute is made up and how we can declare the images.

Note: source set takes 2 values and is separated by a comma after each declaration.

Let’s have a look:

<img src="/photo.jpg" srcset="/[email protected] 1000w, /[email protected] 2x, /[email protected] 3x" alt="" />

You can see that every line is made up out of a file you wish to load in and after that a space with the width of the image’ real size. In this case, we’ve got an image with a width of 1000px. So we say when the width (w) of the screen is 1000px, load in that image.

Now there’s another attribute which I’ve not discussed out there that works together with our sourceset. This is the sizes attribute. Now when sizes has not been specified, it’s default value is always 100vw (100% of your device viewport).

Next one in line is 2x. We’ve discussed this a bit already but it’s the device-pixel ratio we’re specifying here. When the device has 2x the amount of pixels than a regular 1x device, it will automatically grab the image specified and load it in.

You all can guess what 3x is going to do! As you can see srcset is quite a powerful tool to make your images responsive and you didn’t need a single line of CSS for it.

Conclusion

If you’re a developer who’s looking for an easy way to specify your responsive images, source set is the way to go! There are loads of frameworks out there who would make the use of source sets an even bigger asset. Think about how dynamic it could be.

CSS limits us as we can’t target something in a CSS file. The media queries we write will and remain the same. Our HTML can be be changed and manipulated, which opens a lot of doors when it comes to the srcset attribute!

About the author

Niels is UI Engineer and Designer at Ultimate Courses. He specializes in scalable component architecture patterns with HTML and CSS, alongside advanced CSS design systems. Niels moved to England after 23 years in The Netherlands.

Love the post? Share it!

Lots of time and effort go into all our blogs, resources and demos,
we'd love it if you'd spare a moment to share them!

Explore our JavaScript courses

Get started today and join over 50,000 developers.