Show Images of Differing Resolutions Depending on the Viewport Width with srcset

Rory Smith
InstructorRory Smith

Share this video with your friends

Send Tweet
Published 4 years ago
Updated 3 days ago

For small viewports, we want to save bandwidth and we may be dealing with slow speeds; so it's very important that images' filesizes are not too big. In this lesson, we are going to cover how to show a different-sized image than the one seen on desktop.

Instructor: [00:00] Over here in the browser, we have an image which is 1,024 pixels wide. It's quite suitable for desktop, but not so suitable for devices with smaller viewports, because of its dimensions and its file size.

[00:15] What we want to do is show an image with smaller dimensions on smaller viewports. We can do this all inside our image tag in the HTML. The reason we're going to do it inside our HTML is because this should affect our site before we even get to any CSS or JavaScript.

[00:37] To load a smaller image on smaller viewports, we're going to need the srcset attribute. Inside the image tag, we're going to use srcset, and we're going to provide the srcset attribute with a list of images. In this case, they're widths.

[00:56] I have a link to a smaller version of this image, so I'm going to grab that now. I know that this image is 700 pixels wide, so I provide the srcset with 700, and then w for width, rather than px for pixels. After this, I'm going to specify the same image that we're loading in the src attribute, and provide it with 1,024.

[01:28] Now, what's going to happen is the browser is going to choose which of these images is more suitable for its viewport. Let's take a look at what's actually going on here. We're going to open the network tab inside Chrome dev tools.

[01:44] I've disabled cache, so that nothing is stored locally. Let's refresh the page. As we can see down here, the image that we get back is the large one, 1,024 pixels. Let's switch to an iPhone 5, or SE, which is 320 pixels wide in viewport width.

[02:07] We'll refresh again, and this time, we can see that the smaller image is loaded, the 700 pixels wide one. This may seem like a subtle change, but let's say the user is using a particularly slow connection. Let's emulate that now.

[02:26] We'll emulate it with the large image first. Let's see how long it takes to load. That took 7.32 seconds to load. Now, let's do the same thing on the smaller viewport. It took only 4.6 seconds. This could mean a lot, if you have a lot of images stacking up on your page.

[02:50] Another attribute which we can make good use of is the sizes attribute. This allows us to specify a width for the slot that the image is taking up. In the sizes attribute, we're going to pass a media query and a width for the slot.

[03:12] This can't be a percentage, but it can be something like 90 viewport width. Let's specify another one underneath for a different media query. We can set a default one, if there's no media query. That can be the last one in our sizes.

[03:32] Let's see what impact that has on our image. Now, by default, the image takes up 60 viewport width. As we go down, we can see that it takes up slightly more of the viewport width. This can be useful because we may want to apply widths to these images before the CSS even loads onto the page.

[03:59] Lastly, it's worth mentioning that we can actually control which of these images shows, depending on the DPR setting of the device. We can do this using x descriptors. In this case, instead of supplying the width of the image, we could say 1x. For the larger image, 2x.

[04:20] Let's head back to our browser. Up here, we have the DPR that we can get from the menu here. When we set that to one and refresh the page, then we get the smaller image. When we set it to two, we get the larger image.

[04:43] In this way, we can fine tune which images get shown, depending on the kind of device. It's also worth mentioning that if a browser doesn't support these srcset or sizes attributes, it will just fall back to the source value, and the default image will get shown.