srcset - Responsive image loading wrong file
Asked Answered
R

6

5

My goal is to serve different versions (resolutions/sizes) of the same image, which should occupy 100% of the width of the viewport, so I can serve a 800px version to mobile devices (or, generally, devices with smaller displays or slower connections), 1366px and above to larger desktop displays.

The problem is that I'm testing it with the Chromium device emulator and some small screen devices load the 1366px version instead of the 800px: the iPhone 6/7/8 (375px width) loads the 800px image, but the iPad (768px), Nexus 5 (360px) and iPhoneX (375px) all load the 1366px instead of loading the 800px.

I'm not very confident of having understood the sizes directive properly, here's my code, the default src references the 2880px version just to help testing:

<img class="img-fluid" 
    srcset="img/dreamstime_800w_109635242.jpg 800w,
         img/dreamstime_1366w_109635242.jpg 1366w,
         img/dreamstime_2880w_109635242.jpg 2880w"
    sizes="(max-width: 800px) 100vw,
        (max-width: 1366px) 100vw,                      
        2880px 100vw"
    src="img/dreamstime_2880w_109635242.jpg"/>
Realtor answered 29/7, 2018 at 20:43 Comment(0)
B
4

This has to do with retina displays (and their DPI, I think).

From what I've heard, retina displays will pick the first image that is either twice or three times the width of their display, depending on their respective retina display (2x, 3x etc).

Another simple solution would be clearing your browser cache. If your biggest and baddest image has already been cached, Chrome (for example) will always load that image instead.

Belayneh answered 29/7, 2018 at 22:54 Comment(2)
The problem is indeed related to the screen's DPI, this article explains it well: css-tricks.com/…Realtor
Also make sure you test with responsive mode disabled, because responsive mode may change the pixel density of your device. I made a more detailed answer to explain.Discoverer
R
5

Your sizes attribute tells the browser the image is always shown full viewport width, so you could simply replace it with sizes="100vw".

So the browser takes current viewport width, multiply it with screen density, and it gives it the width of the required image. It then takes the closest image from the list in the srcset.

You can't use it to ”serve a 800px version to mobile devices”, because most mobile devices nowadays have bigger density than desktop devices and you can't prevent it with <img srcset… sizes…>.

If you really want to ignore screen density (for what reason?) and:

  • serve smallest images to small devices,
  • serve medium image to medium devices
  • serve large image to large devices
  • keep largest image as the fallback

Then you have to use <picture> with media queries like that:

html <picture> <source media="(max-width: 800px)" srcset="img/dreamstime_800w_109635242.jpg 800w"> <source media="(max-width: 1366px)" srcset="img/dreamstime_1366w_109635242.jpg 1366w"> <img src="img/dreamstime_2880w_109635242.jpg"> </picture>

Rancor answered 2/8, 2018 at 8:49 Comment(4)
I understand and agree with your answer generally, but you can achieve the same by simply using srcset: css-tricks.com/…Realtor
That's not true, unless you remove "so I can serve a 800px version to mobile devices" in your question.Rancor
It would have been helpful if you added some explanation beyond "that's not true", but I've linked an article sustaining my previous claim if you care to elaborate...Realtor
Well, sorry, but I thought my first answer was already pretty elaborate. If you use srcset with multiple images, the browser will take the one it needs to fill viewportxdensity, so if you want to restrict a 800px viewport to an image 800px wide, either you don't provide any image above that size, or you use <picture>. If you only use srcset with images larger than 800px and you have a 2ddpx screen with a 800px viewport, the browser will try to find a 1600px image.Rancor
B
4

This has to do with retina displays (and their DPI, I think).

From what I've heard, retina displays will pick the first image that is either twice or three times the width of their display, depending on their respective retina display (2x, 3x etc).

Another simple solution would be clearing your browser cache. If your biggest and baddest image has already been cached, Chrome (for example) will always load that image instead.

Belayneh answered 29/7, 2018 at 22:54 Comment(2)
The problem is indeed related to the screen's DPI, this article explains it well: css-tricks.com/…Realtor
Also make sure you test with responsive mode disabled, because responsive mode may change the pixel density of your device. I made a more detailed answer to explain.Discoverer
S
1

for future readers - i had a hard time understanding why srcset was totally ignoring my attempts. After a couple hours of frustration and anger i came thru the most obvious answer in the world - i'm working on a Retina Macbook Pro, and i wasn't triggering pixel density.

I changed it to

<img class="<?= $image_class;?>" data-caption="<?php echo $image['alt']; ?>"
data-src="<?php echo $image['sizes']['medium']; ?>"
data-srcset="<?php echo $image['sizes']['medium']; ?> 600w 2x, 
<?php echo $image['sizes']['large']; ?> 1280w 2x"
sizes="(min-width: 150px) 600px, 100vw"
width="150" height="150"
alt="<?php echo $image['alt']; ?>">

and everything worked - at least i could figure out something was happening. Phew. Merry Xmas everybody!

Stemson answered 25/12, 2018 at 9:26 Comment(0)
F
1

Testing my web pages with the Chrome emulator, I sometimes found (like you did) that an image larger than necessary was apparently being loaded, particularly on small mobile devices. I finally realized that this was not an error on my part but Chrome pulling a larger image from cache if it happened to have one there. Clicking the checkbox in the emulator to disable the cache while testing, the problem went away and the sizes I expected to see loaded were in fact loaded.

Fougere answered 19/3, 2019 at 4:23 Comment(0)
D
0

I noticed that when the chrome devTools is open with the responsive mode enabled, my device pixel ratio changed from 1 to 2. As a result, even with cache disabled in network tab, it seemed to me the browser was loading a larger file than necessary, but it's because the pixel ratio changed when:

  1. the devTools was open
  2. responsive mode was enabled

You can double check with a simple javascript alert the pixel ratio at any given time:

<script>alert(window.devicePixelRatio)</script>

It's likely you have responsive mode enabled if you try to load your page at multiple width for testing, but it's also what might change the pixel density. Thus, it might just work as intended like it was for me.

Discoverer answered 13/8, 2021 at 23:51 Comment(0)
V
-2

simple answer:

sizes="(max-width: 999px) 50vw, 100vw"
Vashti answered 17/8, 2021 at 17:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.