Responsive images with srcset and sizes attributes vs picture element

In this article, learn all about how srcset and sizes attributes work and what are the differences between the picture element.

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. I will help you understand these underused or misused HTML <img> tag attributes for responsive images.

I will also talk about picture vs srcset and when to use each technique.

Let’s dive in.

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. Or different-sized images showing the same motive to be precise. Just like a cute dog example below demonstrates.

Cute dog demonstrating srcset attribute

Fig 1: Cute dog demonstrating srcset attribute

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

You can see srcset in action on a dog pictures above and below. 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.

srcset attribute is well supported

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.

Art direction use case

This is an art direction use case that calls for <picture> element. More on that topic read further down below.

Puppy demonstrating srcset attribute downside

Fig 2: Puppy demonstrating srcset attribute downside

srcset syntax

So how to properly use srcset and sizes attributes? This is the code:

<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.

How does the browser use the srcset attribute

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 the 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

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.

Puppy demonstrating picture element

Fig 3: Puppy demonstrating picture element use case

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.

Now, despite having highest resolution image in the cache, Chrome browser will request smaller images on lower resolution screens.

<picture> syntax

So how to properly use <picture> element? This is the code:

   <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">

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 are two more attributes we can use within <source> tag: sizes and type. Check it out here. Picture element is also well supported nowadays.


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

11 thoughts on “Responsive images with srcset and sizes attributes vs picture element”

  1. Very and easy explanation.The best explanation that I found! Thank you so much!
    If I understood the article correctly the sizes attribute don’t necessary to use. Only if you want to declare for the browser which image to download on different viewport widths.

  2. Dude, thank you so much for writing this! I just read 4 other articles on the same exact topic and was entirely confused about how the sizes attribute worked until reading yours 🙂

    Very much appreciated!

  3. Excellent tutorial. Clear explanation, examples and reference code. I had same experience as noted above, of reading half a dozen other articles which were both confusing and overly complex. In contrast, after reading your article I was up and running in five minutes. Thanks very much.

  4. While this sounds great in theory, I think using the img tag with srcset and sizes doesn’t work quite as you’d expect.

    Since today’s phones have such high density screens, the phone’s browser will end up loading a high resolution image anyway – because it has so many pixels to work with.

    So as wonderful as using srcset and sizes seems when you’re playing around with it on a desktop computer, it may not actually be worth the trouble, because in many cases the browser will choose the higher res image anyway.

    • Hi Charlie, thanks a lot for your comment, and you are right, browser will make it’s own decision on which image to use in the case of img tag with “srcset” and “sizes”, but you can use “picture” element if you don’t want browser to decide 😉 Maybe I didn’t emphasize it enough, but example 2 should work just fine even on your phone

  5. Ok, so you wrote “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. “.

    So why put the second line at all, if it does nothing? What is the purpose of having with several ‘s ?

    • It does something 🙂 It applies on devices above the 552px as first line would be ignored only in that case. It also prevents the medium image showing for the widths above 1062px


Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.