Responsive images – only largest image in srcset created

Hi. I’m working with responsive banner images but, for some reason, only the largest image size specified in the srcset is being created in the media folders.

The use case is that I have two banner images on top of one another, with the top one fading in and out with a CSS animation to create a changing image effect. Hence the foreach statement. However, even if I use one image and an if statement, the outcome is the same.

My banner image snippet contains the following…

<?php $images = $page->bannerimg()->toFiles(); foreach($images as $image): ?>
<img
    class="absolute inset-0 w-full h-full rounded dark:brightness-[0.7]"
    loading="lazy"
    alt="<?= $image->text() ?>"
    src="<?= $image->resize(440)->url() ?>"
    srcset="<?= $image->srcset([440, 768, 1024, 1340]) ?>"
    sizes="(min-width: 1420px) 1340px,
           (min-width: 768px) 1024px,
           (min-width: 440px) 768px,
           440px"
    width="<?= $image->resize(1340)->width() ?>"
>
<?php endforeach ?>

(As far as I can tell, I have the code set up correctly as per the Cookbook recipe.)

When a relevant page renders, the image tags for both banner images do include all the relevant variants in the srcset, i.e. -440x.webp, -768x.webp, etc. And, in the relevant media folders, the ‘jobs’ subfolders do contain JSON files for each corresponding size. However, only the largest -1340x.webp version of each image has actually been generated. As a result, even though the srcset lists the different sizes, the largest image is the only one available and so that’s what appears in the Dev Tools Network tab.

I’m using TailwindCSS, so the w-full and h-full classes mean that image width and height are both set to 100% of the container size. In theory, I shouldn’t need them because of inset-0 but I added them as part of my investigation.

I tried adding a height line as well – height="<?= $image->resize(893)->height() ?>". That created a new -893x.webp image but with exactly the same dimensions (1340x893) as the -1340x.webp version.

What am I missing? No doubt it will turn out to be something obvious! :wink:

Kirby version is 3.9.6.1.

Many thanks.

At what browser widths are you testing? When resizing the browser window, do you clear the cache in between?

Hi, Sonja.

I’m testing at lots of different sizes using the device toolbar in Chrome Dev Tools. Different mobile sizes, both iPhone and Samsung, iPad Air, iPad Mini, Surface Pro in portrait and landscape. Plus larger sizes with the ‘responsive’ setting. And yes, I’m clearing cache each time, both in the Panel and in the browser. I’ve also deleted the media folder to really start from scratch.

I’ve been using the Dev Tools Network tab. “Disable cache” is checked and I’ve been clearing the network log each time as well.

But whatever device/width I select, it’s still the large -1340x.webp images that are getting created and rendered.

As part of my investigation, I’ve added a <link> tag in the <head> to preload the first of the banner images. And that does indeed create a -440x.webp image in the relevant media folder. So, the preload ‘resize’ command seems to work, and the width (and height) attributes inside the <img> tags are creating the -1340x.webp images. But the srcset sizes seem to be ignored, even though they are generating JSON jobs.

In case it helps, you can check it out at this page on my staging site.

Many thanks.

Hm… first load small browser window, loads the 440x

Sonja, I got confused because the 440 version only appeared when I specified that size in the preload.

I think it’s a DPR issue, so it is my ignorance after all! The image creation process is working. It’s just a case of me getting the sizes settings right.

I swear that I was previously only seeing the 1340 image even on an iPhone SE emulation. But that’s now showing the 768 version. 375px device width at 2x density is 750px, so the browser defaults to the 768 version. What confused me is that is still showing the 1340 version on a Samsung Galaxy S8+. But it turns out the native resolution of that device is 1140px width, so that might explain it.

However, I thought that with my size settings in the <img> tag…

    sizes="(min-width: 1420px) 1340px,
           (min-width: 768px) 1024px,
           (min-width: 440px) 768px,
           440px"

…I would be forcing the image size. So, with the S8+ example, the 1140px device resolution is more than 768 but less than 1420, so why is that not getting the 1024 version of the image?

But ideally I want to display, for example, the 440 image on all mobile devices and the 1024 version on all tablets, regardless of DPR. I obviously need to do something more with the sizes settings but I’m not quite sure what. (I tried min-device-width instead of min-width and it made no difference.)

Yep, the sizes aren’t working as I intended. Using the Dev Tools ‘responsive’ option, to try to bypass the DPR question, if I adjust the width of the viewport, clear the network log, clear cache and reload…

  • Viewports up to 439px get the 768 image
  • Viewports 440px and above get the 1340 image

But what I’m trying to achieve is…

  • Viewports up to 439px get the 440 image
  • Viewports 440-767px get the 768 image
  • Viewports 768-1023px get the 1024 image
  • Viewports 1024px and above get the 1340 image

(I have realised that I needed to correct the min-width: 1420px to 1024px.)

But if the the DPI value is > 1, then the browser will automatically pick the next best fit.

Thanks, Sonja. At least the srcset is working after all. The issue is my confusion over DPI!