picture srcset with webp - how to implement sizes?
Asked Answered
P

2

7

I'm trying to have a picture tag with WebP support.

( load image-full if the screensize is over 1024px, image-1024 for max-width 1024px, image-768 for max-width 768 px and image-500 for max-width 500px )

I've got this code, and w3 validator is complaining that: When the srcset attribute has any image candidate string with a width descriptor, the sizes attribute must also be present.

How do I implement sizes into this? Is there a better/different way I should do this?

<picture>
// load webp in different sizes if browser supports it
<source media="(min-width: 1025px)" 
    srcset="webp/image-full.webp"
    type="image/webp">
<source media="(max-width: 1024px)"
    srcset="webp/image-1024.webp" 
    type="image/webp">
<source media="(max-width: 768px)" 
    srcset="webp/image-768.webp"
    type="image/webp">
<source media="(max-width: 500px)" 
    srcset="webp/image-500.webp"
    type="image/webp">

// load jpg in different sizes if browser doesn't support webp
<source media="(min-width: 1025px)"
    srcset="siteimages/image-full.jpg" 
    type="image/jpeg">
<source media="(max-width: 1024px)"
    srcset="siteimages/image-1024.jpg" 
    type="image/jpeg">
<source media="(max-width: 768px)"
    srcset="siteimages/image-768.jpg" 
    type="image/jpeg">
<source media="(max-width: 500px)"
    srcset="siteimages/image-500.jpg" 
    type="image/jpeg">

// fallback in different sizes, as well as regular src.
<img 
    srcset="siteimages/image-1024.jpg, 
        siteimages/image-768.jpg,
        siteimages/image-500.jpg"

    src="siteimages/image-full.jpg" 

    alt="image description"
    class="myimageclass">
</picture>
Pimental answered 8/4, 2020 at 7:12 Comment(0)
I
9

While providing multiple srcset in img tag browser needs both scrset and sizes attribute to help the browser pick the right one.

You can add update code like below and it should work without complaints -

<picture>
// load webp in different sizes if browser supports it
<source media="(min-width: 1025px)" 
    srcset="webp/image-full.webp"
    type="image/webp">
<source media="(max-width: 1024px)"
    srcset="webp/image-1024.webp" 
    type="image/webp">
<source media="(max-width: 768px)" 
    srcset="webp/image-768.webp"
    type="image/webp">
<source media="(max-width: 500px)" 
    srcset="webp/image-500.webp"
    type="image/webp">

// load jpg in different sizes if browser doesn't support webp
<source media="(min-width: 1025px)"
    srcset="siteimages/image-full.jpg" 
    type="image/jpeg">
<source media="(max-width: 1024px)"
    srcset="siteimages/image-1024.jpg" 
    type="image/jpeg">
<source media="(max-width: 768px)"
    srcset="siteimages/image-768.jpg" 
    type="image/jpeg">
<source media="(max-width: 500px)"
    srcset="siteimages/image-500.jpg" 
    type="image/jpeg">

// fallback in different sizes, as well as regular src.
<img 
    srcset="siteimages/image-1024.jpg 1024w, 
        siteimages/image-768.jpg 768w,
        siteimages/image-500.jpg 500w"

    sizes="(max-width: 1024px) 1024px,
            (max-width: 768px) 768px,
            (max-width: 500px) 500px"

    src="siteimages/image-full.jpg" 

    alt="image description"
    class="myimageclass">
</picture>

In short we are telling browser to load the image referenced in the srcset list that most closely matches the chosen slot size

Responsive Images Detailed Tutorial

Inexpensive answered 14/4, 2020 at 10:51 Comment(5)
Thank you! Works great. I wasn't sure where to add it, several tutorials added a 800w or a 2x somewhere inside the source tag too. In the example you linked to it's not clear to me what <img sizes="(max-width: 600px) 480px,800px"> does? For a max-width screensize of 600px, it's serving ..both the 480px and the 800px size images?Pimental
No problem.For a max-width screensize of 600px it will pick 480px image and 800px image for rest of screensizes.Inexpensive
funny if I can't really write a set into the srcset attribute of source, or could I?Leathers
you also have to reverse the sources order from the smallest to the biggest to make it work, as i tested on FirefoxLeathers
The sizes attribute here has its pieces in the wrong order. The first match is used, so for a small screen, say 400px, it'll match max-width: 1024px first and so load the largest image, where surely you want it to load the smallest.Gesundheit
M
9

Building on @varun's answer, you can simplify the code a bit:

  • improvement: image/jpeg not needed if it's already in <img> - browsers fall back automatically
  • improvement: combine multiple <source> tags.
  • fix: add default width of 100vw to sizes tag (i.e. viewports wider than 1024px not defined)
  • fix: media tag is for art direction, not for resolution switching, see Mozilla's guide on the difference
<picture>
    // load webp in different sizes if browser supports it
    <source type="image/webp"
        sizes=" (max-width: 500px) 500px,
                (max-width: 768px) 768px,
                (max-width: 1024px) 1024px,
                100vw"
        srcset="
          webp/image-500.webp 500w,
          webp/image-768.webp 768w,
          webp/image-1024.webp 1024w,
          webp/image-full.webp 1920w
        "
        >
    // fallback on original src.
    <img 
        srcset="siteimages/image-1024.jpg 1024w, 
            siteimages/image-768.jpg 768w,
            siteimages/image-500.jpg 500w"
        sizes=" (max-width: 500px) 500px,
                (max-width: 768px) 768px,
                (max-width: 1024px) 1024px,
                100vw"
        src="siteimages/image-full.jpg" 

        alt="image description"
        class="myimageclass">
</picture>
Merow answered 25/10, 2021 at 19:12 Comment(3)
Your sizes attribute is in the wrong order. See developer.mozilla.org/en-US/docs/Learn/HTML/… which says that the browser will choose from the srcset based on the first matching element of sizes. That means in your case with a 400px viewport, the (max-width: 1024px) will match and it'll load a needlessly large image. It should be smallest through to largest, then the fallback.Gesundheit
Thanks @tremby, good catch.Merow
@Merow 1) Thanks for providing this much more structured & readable way! I will go with this one as my code template. 2) Style hint: Please be more explicit in such a comment, e.g. "Thanks tremby, good catch. Corrected my code snippet accordingly. B/c "Good catch" is certainly a respectful reaction to your fellow feedback-giver but only standing by itself leaves other readers uncertain whether that feedback was integrated in the above answer or not. Every reader then needs to check this by him/her-self to reassert oneself. Thanks.Patrolman

© 2022 - 2024 — McMap. All rights reserved.