I’ve been discussing the importance of serving scaled images and optimizing images for faster page load time before. One more piece in the puzzle when it comes to images on the web is using srcset and sizes attributes. This article is a tutorial to help you understand these underused or misused HTML <img> tag attributes for responisve images. I will also talk about picture vs srcset and when to use each technique.
srcset benefits for page load time
When you use the srcset and sizes attributes on an <img> element, you are giving the browser necessary information to make a decision what image to request and serve to user. It is used to serve same image with different resolutions for different devices.
So how exactly srcset attribute can benefit page load time? Imagine the situation where you have a big hero image showing in full width to your desktop visitors. In case you can’t imagine it, here is the sample page I created for demonstration purposes. I created dummy images with different background and text so you can tell them apart easily, but normally you would see the same image. Or different-sized images showing the same motive to be precise. Just like a cute dog example below demonstrates.
OK, so you wouldn’t want to serve that big hero image to users visiting from mobile devices. They would have to download a much bigger image than necessary. This is a waste of time and bandwidth, not to mention it compromises UX. Maybe you have not been thinking about this, because GTmetrix won’t alert on this issue.
GTmetrix reports when you are serving huge images on desktop where you don’t need them. But what about the situation when you serve a properly sized image on desktop which is being scaled down for a mobile device by the browser? Cue srcset.
srcset in action
So head to the sample page for a moment and play around with the size of the browser window to understand what’s going on on different viewport widths in Example 1. You can also see srcset in action on a dog pictures above and below, but you will be able to understand it better with different looking images. But before you do, I’ve got one tip: use Firefox browser for this mission.
Chrome browser is handling the srcset attribute differently. It will still download appropriate image, but if it already downloaded highest resolution image, you won’t be able to see the changes when scaling browser window up and down. This makes sense – if the browser already cached the highest resolution image, there is no need for another request to the server. Chrome will serve a scaled high-resolution image.
Firefox is behaving differently, so it is a better tool for testing. But don’t worry, srcset is well supported by browsers. You can check that here. If a user visits your site using a browser that doesn’t support the srcset attribute, good old src attribute will be used instead. It is important to include it as well.
Below is one more example of srcset in action, but this time puppy on the picture is way to small on the mobile devices where 360px X 200px image is used. This is an art direction use case that calls for <picture> element. More on that topic read further down below.
So how to properly use srcset and sizes attributes? This is the code I used for displaying Example 1 Hero images on the sample page:
<img src="hero-big.jpg" srcset="hero-small.jpg 450w, hero-medium.jpg 960w, hero-big.jpg 1500w" sizes="(max-width: 552px) 450px, (max-width: 1062px) 960px, 1500px" alt="Learnedia Hero" />
- The first line is pretty straight forward. It is a fallback option if the browser doesn’t support srcset attribute. In this case, we want big Hero image to be downloaded so the page looks good on the desktop device.
- The second line is where the magic happens. We are defining three image sources separated with a comma. But right after the image source, we define the actual width of the image using the integer representing the width in pixels with w appended. This is important because browser now knows the actual size of the image before downloading it first.
- The third line is where we declare at which viewport widths we want a particular image to be downloaded. This is done using sizes attribute. This is where people commonly make mistakes. So it is important to fully understand the sizes attribute. It doesn’t tell the browser to download a certain image based on the width of the image parent container. It tells the browser which image to download on different viewport widths.
In my example above, I am using sizes attribute to tell the browser to download image with a width of 450px on devices with viewport width up to 552px (mobile phones). The browser uses the information given within srcset attribute about the width of the image to decide which of the three images is the most appropriate. Simple, right? And effective, too.
So, browser will now use 450px image (hero-small.jpg) for mobile phones and 960px image (hero-medium.jpg) for medium devices (up to 1062px). Note that we don’t need to declare device width for the third image. We just need to declare the size of the image for that scenario (1500px) when device width is above 1062px. That’s it!
Example 3 with dummy product images is more complex, but that only shows you how powerful this srcset technique really is. I combined it with flexbox to show how product images don’t have to look bad on some viewport widths which is often the case. If you have a 4 column layout for desktop and 1 or 2 column layout for smaller devices, you want to serve images with different sizes (resolution) for different layouts. This is where srcset and sizes attributes come in handy.
<picture> element and when to use it
Example 2 on my sample page and puppy image below are demonstrating use of the <picture> element. When to use <picture> element? How is it different from img element with srcset and sizes attributes? In case you are using <picture> element, you are strictly telling browser which image to use on different viewport widths.
This is different because now browser won’t make a decision on it’s own which image to serve. That is useful when you are serving different images on different viewport widths. It could also be variations of the same image cropped differently to look better on some devices. See the puppy above? This time I used three differently cropped images so it looks better on smaller devices.
picture vs srcset
I cropped out unnecessary area surrounding the puppy making it stand out more on smaller devices than it was case on fig 2. In this case we are talking about the art direction use case. More info here. Another cool example of the art direction here.
You can check out my sample page now, but this time you could use Chrome browser as well. You will see that now, despite having highest resolution image in the cache, Chrome browser will request smaller images on lower resolution screens.
So how to properly use <picture> element? This is the code I used for displaying Example 2 Hero images on the sample page:
<picture> <source media="(max-width: 552px)" srcset="hero-small.jpg"> <source media="(max-width: 1062px)" srcset="hero-medium.jpg"> <img src="hero-big.jpg" width="1500" height="400" alt="Hero"> </picture>
We are creating <picture> element, just like we create <div> element. Inside, we create child elements using <source> and <img> tags. While <img> tag now looks pretty straight-forward, there are some new attributes that we are using within <source> tag.
- We are using media attribute to strictly determine which image browser has to use on a certain device width. In the first line, I defined hero-small.jpg image for the devices with viewport widths up to 552px.
- On the second line, there is new media query for devices up to 1062px. Now, you would think that this rule will override the first line, serving hero-medium.jpg image for the devices with viewport width up to 552px as well. This, however, is false. Thing is, browser uses first source that has a rule that matches and ignores the rest. This means we don’t have to modify the media query by also adding a rule min-width: 553px on the second line.
- The third line is just a regular <img> tag that will be used by default if browser doesn’t support <picture> element. Also it serves as a source for viewport widths above 1062px.
There you have it, hope you understood additional srcset and sizes attributes for <img> and what benefit they carry for responsive design images. We also talked about <picture> element and how it differs from the technique above. You can now read my other articles about serving scaled images and optimizing images on the web.
If you have any questions please don’t hesitate to comment or consult additional resources below. If you find the article helpful please share with others 🙂
Other resources from the web on the topic
- Responsive Web Images online course – learn everything there is to know about art direction, image types, picture, srcset, sizes, responsive image use cases and techniques
- Responsive Images Done Right: A Guide To <picture> And srcset
- Don’t use <picture> (most of the time)
- Why We Need Responsive Images
- Why We Need Responsive Images: Part Deux
- Sensible jumps in responsive image file sizes