Srcset not working in Chrome (but in Firefox and Safari)

I have setup a srcset rule which works fine in Firefox and Safari, but Chrome always downloads the original file.

This is my twig:

{% for image in p.media.images %}
  <picture>
    {{ image.derivatives(320,2720,300).sizes('100vw').html }}
  </picture>
{% endfor %}

This is the output:

<img alt="" 
src="/user/pages/foldername/_DSC4394.jpg" srcset="
/images/path-dsc4394320w.jpeg 320w, 
/images/path-dsc4394620w.jpeg 620w, 
/images/path-dsc4394920w.jpeg 920w, 
/images/path-dsc43941220w.jpeg 1220w, 
/images/path-dsc43941520w.jpeg 1520w, 
/images/path-dsc43941820w.jpeg 1820w, 
/images/path-dsc43942120w.jpeg 2120w, 
/images/path-dsc43942420w.jpeg 2420w, 
/user/pages/foldername/_DSC4394.jpg 2560w" 
sizes="100vw">

I noticed that the original file “repeats” itself into the last line of the srcset images: /user/pages/foldername/_DSC4394.jpg 2560w It’s not there in the example in the documentation and Safari/FF also don’t seem to care. When I remove the line in the inspector Chrome downloads another image, but also not necessary the correct one.

@luap, What might be happening is the effect of <picture> on the way the browser selects the image. See MDN docs on <picture>.

Quote from the docs:

The browser will consider each child <source> element and choose the best match among them. If no matches are found—or the browser doesn’t support the <picture> element—the URL of the <img> element’s src attribute is selected. The selected image is then presented in the space occupied by the <img> element

[bold is added by me]

Since you have no <source> element, the browser will always pick /user/pages/foldername/_DSC4394.jpg, which is the value of src attribute.

What happens if you remove the <picture> element?

Note: If you only need responsive images, the <img> element with a srcset will do. <picture> is used for 'art-direction`: serving different (content wise not size) image at different viewport sizes. See MDN intro on Reponsive Images

You said:

I noticed that the original file “repeats” itself […] It’s not there in the example in the documentation

I think it does also in the docs. See below after a bit of formatting:

<p>
<img alt="Retina Image" 
src="
/images/8/9/7/c/3/897c350cb3b7f7b9eb358aa4e2a728380e34c73c-retina1x.jpeg" 
srcset="... other sizes deleted
/images/8/9/7/c/3/897c350cb3b7f7b9eb358aa4e2a728380e34c73c-retina1x.jpeg 1440w" 
sizes="(max-width:26em)+100vw">
</p>

Interesting! The example from the documentation is also not working in Chrome! I was linking to the doc, but was actually looking & pasting code from this blog-post: https://getgrav.org/blog/retina-responsive-images

The example from the Blog post works in Chrome, from the documentation does not.

Removing the <picture> element also didn’t change anything, unfortunately.

@luap, Since I have been playing around with responsive images before and have found no issues using Chrome, I tried the code you posted.

I did the following:

  • Standard fresh Grav (v1.6) installation using theme Quark
  • Added your HTML snippet for the <img> into /pages/01.home/default.md
  • Resized the console of Chrome to emulate viewport resizing.

Watch the ‘width’ counter on top and the Network panel at the right.

responsive

Note that the image isn’t shown in above animation because the images do no exist. However, Chrome tries to download the correct url.

That’s good news, but do you have an idea how to proceed for my project? Note that I am writing my own template and calling page media images and not via “content”.

Can you also reproduce that the same error is happening inside the grav documentation? I see no new downloads when resizing in chrome, but do so in FF.

@luap, It doesn’t matter whether the <img> definition comes from content or Twig. It’s only the generated <img> HTML in the resulting page that matters.

Anyway…

  • I have dropped your Twig code into Quarks ‘/templates/default.html.twig’ and renamed p.media.images into page.media.images.
    Chrome is working as expected.
  • I have dropped the code from the blog you mentioned into ‘/templates/default.html.twig’
    // formatted it for clarity
    
    <img src="/images/cache/sample1x.jpg" 
      alt="My Responsive Image" 
      srcset="/images/cache/sample1x.jpg 733w, 
              /images/cache/sample@2x.jpg 1466w, 
              /images/cache/sample@3x.jpg 2200w" 
      sizes="100vw" />
    
    Chrome is working as expected
  • As a bonus, I added the <picture> element in Twig.
    Chrome is loading the right picture, but that is not as expected according the docs from Mozilla Developer Network I referred to before.

By the way, if you start using a wide screen and then making it smaller, you might not see a different image being loaded, because the largest image is already loaded in cache. For all smaller viewports, the large image from cache will simply be resized which is faster then loading a new image.

@pamtbaau Thanks you for your effort. It’s good to know that it doesn’t matter if the code is coming from content or twig.

But I noticed your example html is different to the one I get, by the names of the sizes. Your filenames end with @2x/@3x, not with the width of the image. As far as I understood there are generally (not only in grav) two ways of using srcset: either for providing the same size for standard, x2 and x3 resolutions, or, to provide a bunch of different sizes and then the browser selects the one it wants to choose.

To be more specific: How could I debug my code, what could I try within my template to see where the error comes from (if it’s not a grav issue)?

@anon76427325 I did some more testing and it’s even more strange.
Yes, adding my code to the default.html.twig of a fresh grav install works perfectly fine.

I now noticed, that while increasing the viewport size, chrome downloaded new images, but not all of them. I am building a onepager with different sections (which are pages in the BE). The first image inside each page is always the original file (not correct), the ones after that behave correctly.

This is my entire twig for the homepage:

{% extends 'partials/base.html.twig' %}
{% block content %}
	{% for p in page.collection %}
		<section id="{{ p.slug() }}">
			{# other stuff here #}
			<div class="image">
				{% for image in p.media.images %}
					{{ image.derivatives(320,2720,300).sizes('100vw').html }}
				{% endfor %}
			</div>
			{# other stuff here #}
		</section>
	{% endfor %}
{% endblock %}
  • Do you have any suggestion how to further debug?
  • I also noticed that any max-size above 1520px is not working, is that somewhere more cleary documented than in the doc? It just says

For the moment it does not work inside markdown, only in your twig files.

@luap, If it is working in a fresh Grav install, there must be something peculiar in your site which has not been brought up to the table yet…

If you willing to share your site, I will have a look at it. If you’re not willing to share it in public, you may PM me.

@anon76427325 that is very kind! I was trying to do so, but ran into some htaccess issues. As soon as I have fixed those, I’ll send the site over.

was able to help me out.

The reason for the behavior that only the first image of each section was displayed in fullsize, was that, the first image was part of the site’s menu – and there I hadn’t activated any downscaling yet. So it was my mistake.

However, Chrome did handle the image downloading differently than Firefox and Safari. Both of them were downloading the fullsize for the menu and the srcset-downscaled inside each section, while Chrome only took the higher resolution.

Thanks @anon76427325 for the help again.