HTML: How to structure the <picture> element?

Hi,

I hope asking a question that is not directly related to Kirby is OK.

I have been struggling with setting up the <picture> element, especially where to put srcset and sizes when using different file formats.

The srcset attribute seems to go on every <source> element, but what about the <img> tag? Do I need to provide a value for both src and srcset (and maybe even sizes)?

In other words, in the following markup:

  • Is <source> set up correctly?
  • What attributes are needed for <img>?
<picture>
  <source
     type="image/avif"
     srcset="xxx"
     sizes="xxx">

  <source
     type="image/webp"
     srcset="xxx"
     sizes="xxx">

  <img
    src="???"
    srset="???"
    sizes="???">
</picture>

I didn’t add actual values for srcset and sizes, as I’m only interested in the structure at this point.

Cheers,

Stefan

Hi Stefan,

yes, picture is complicated and can become very verbose.

You can think of it like this:
When you use picture, you need an img element within it. It provides the common infos like alt text and image dimesions and serves as fallback for older browsers with the good old src attribute. If img is used within picture, you don’t need srcset, as this is provided within the source elements

Now, you can add source elements for different image formats. They need the srcset attribute (no src as this is already used within img)

With srcset you provide different sizes of the same image. The browser picks what fits best. To help the browser making its choice you can also add the sizes attribute, telling the browser, how large the image is compared to the viewport size. For example sizes="100vw, (min-width: 1000px) 50vw" tells the browser, that the image ist displayed at the full-size. From a viewport of 1000px it’s only half of the viewport width (50vw). If your image is always full-size, e.g. a big hero image, you can omit the sizes attribute.

So, to wrap it up:

<picture>
  <source
     type="image/avif" -> required
     srcset="xxx" -> required
     sizes="xxx"> -> optional
 
  <source
     type="image/webp" -> required
     srcset="xxx" -> required
     sizes="xxx"> -> optional

  <img
    src="???"  -> required, fallback
    srset="???" -> no, not if img is within picture
    sizes="???"> -> no, not if img is within picture
    alt="" -> accessibility
    width="" -> avoid layout shift
    height="" -> avoid layout shift
</picture>

Maybe this thread might be of interest, with Kirby code example:

1 Like

Thanks for your explanation! Now, for the fallback src image, do I need to use the largest size among the available images?

In your linked thread, you wrote:

<img src="<?= $image->thumb(['format' => 'jpg'])->url() ?>"

so I couldn’t see what size the image was.

As for the thumbs, you can create your on presets, described here:

Here, the question is, do you want to sacrifice quality or loading times?
I’d use the largest image, but shrink down quality.
You could also add a source element with JPEG as image type and different sizes in srcset. I’m not sure how well iOS support for WebP is, currently, so maybe we still need a good JPEG support.

For me, load time is most important, so reducing the quality is a good idea. Thanks for the tip!

Out of curiosity, do you also cater to high-resolution screens over 1920px using images of twice the size?

I’m not a designer, if it’s necessary. I’m just worried that browsers will use 2x resolution images on modern screens, thus reducing the size benefit of providing smaller images.

I’m just fine with 1920 px, even for high-res screens.
Beyond Laptops there are not much high-res screens around, so currently no need for this.

1 Like

Thanks, you helped me a lot!