DEV Community

Jesse Fulton
Jesse Fulton

Posted on

Explain HTML's img srcset vs picture tag Like I'm Five

I'm trying to write a global helper template to automatically serve responsive images across a website. But first: what is the difference between implementing responsive images on a webpage using <img srcset="..." sizes="..."> versus using a <picture> element with <source>s?

I found this MDN article on responsive images, but it's way too long for me this late in the day. Thanks internet!

Top comments (7)

Collapse
 
ben profile image
Ben Halpern

srcset is for "resolution switching" and <picture> is for "art direction".

Basically srcset is where you give the browser several different versions of the image to avoid loading big pictures on small screens and vice versa. <picture> is where you want fine-grained manipulation of which image shows up given some media queries. Maybe you want a specifically cropped tall splash screen on mobile and a wide one on desktop. They're essentially different pictures and you don't want to leave the details to chance.

srcset sort of builds on src but gives the browser a chance to render the best version for the scenario and <picture> is useful if you want explicit control over how things are displayed, which is typically not necessary compared with srcset.

I'll note that the last time I tried to use srcset I couldn't get around a frustrating Safari bug. I've never used <picture> so can't say if that works as expected.

Collapse
 
jessefulton profile image
Jesse Fulton

<picture> is useful if you want explicit control over how things are displayed, which is typically not necessary compared with srcset

But can't you do the same thing with each of them? I guess, I'm not seeing any functional difference between the two - they seem to only vary in the implementation. They both allow you to bias the browser into downloading an "optimized" version of an image based upon media queries, just in slightly different syntaxes. Does that sound correct?

Although, if one doesn't work on Safari (thanks for the tip!) that's reason enough for me to use one over the other (IE support is another issue though...)

Collapse
 
ben profile image
Ben Halpern

With srcset the browser does the math on retina displays and other scenarios where pixels for you might not be pixels for the user. With <picture> you'd have to do this all yourself.

Collapse
 
joerhoney profile image
joerhoney

In looking into this question myself, I've found that <picture> really is better for art direction, as it will adjust to the viewport/layout on the fly. Yeah, you can use srcset on <img> to load different image files on initial page-load, but when you adjust the screen size or orientation, it won't load or switch to your more appropriate image file (unless you refresh, maybe). <picture> on the other hand, will.

Now while I hate to answer a question with another question, I haven't tested whether <picture> loads all image files on page-load, or if it just loads them as needed, making another query after the page has already loaded, like an AJAX call. But somehow all of the image files are available for the <picture>, but for the <img> with srcset, only the file loaded on page-load is available.

This post demonstrates a good example of that (see fig. 3):
learnedia.com/responsive-images-sr...

Collapse
 
joerhoney profile image
joerhoney

Here's another really good article on it (even better, I'd say):
css-tricks.com/responsive-images-y...

If you only read one of these, read this one.

My basic conclusion is that for general use, <img> with srcset is more ideal. When you really need to be specific and have higher control of art direction <picture> gives you the control that <img> + srcset doesn't.

Collapse
 
matsp profile image
Mats Pfeiffer • Edited

I have no idea why this is working inclusively Safari:

<picture>
  <source srcset="${props.image.srcSet}">
  <img src="${props.image.src}">
</picture>

Maybe Iam working too long on srcset and Safari that I tested something different...

Collapse
 
bobhy profile image
Bob Hyman

I'm going to say, <picture> gives you direct ability to choose different images for arbitrarily different media conditions. With img@sizes, you only get to select an image by specifying its width, and have to hope (or carefully arrange) that selects the image with the desired height, resolution or content.

Usually, we're only concerned with selecting from images that differ in size, orientation or (maybe) resolution, and you might be able to avoid using <picture> with a convention: perhaps your landscape images all have widths ending in 0, portrait mode picture widths end in '1' and high resolution `2' and '3'.

But if you want to more complex things, like displaying an SVG in some cases and JPGs in others, you'll probably find it more straightforward to use <picture> and just enumerate the cases.