Img with srcset and dimensions does not load the image I expect

I am trying to optimize a page consisting of a grid of images with breakpoints that allows using 1, 2, 3 or 4 columns.

html looks like this:

<img srcset=" image-300x200.jpg 300w, image-original.jpg 600w" sizes=" (min-width: 1px) calc( 100vw * (0.94 * 1.000) * 1.00 ), (min-width: 480px) calc( 100vw * (0.94 * 0.905) * 0.50 ), (min-width: 768px) calc( 100vw * (0.94 * 0.850) * 0.33 ), (min-width: 981px) calc( 100vw * (0.94 * 0.835) * 0.25 ), 280px" alt="E-Books customer service for Dutch Libraries" width="400" height="284">

The calc () functions may look a little more complicated, but I tested them with different viewport widths and then checked the image size in the browser and math.

For completeness, here is what it does:

[viewport width] - [94% container width] - [column gutters] / [nr of columns]

But no matter what I try, Chrome (almost yay for consistency) always selects a large image, even if the img size on the screen is well below 300 pixels. I checked this in developer tools> inspector> properties> img> currentsrc as mentioned in this answer

Can anybody help me?

+5
source share
1 answer

I think I figured it out. It seems that media queries are not working as I expected.

For example, using these rules:

sizes=" (min-width: 1px) ... (min-width: 480px) ... (min-width: 768px) ... "

one would suggest that

  • Line No. 1 is true when the screen is> 1px wide
  • Line number 2 is true when the screen is> 480 pixels, top line # 1
  • Line No. 3 is true when the screen is> 768px, overrides lines # 1 and # 2

This is not how it works, at least in practice. I think the browser is simply looking for a rule that evaluates to true and calls it day.

So this is simple:

  • Line number 1 is correct! Done! Application of the rule! Easy!

When I looked at my rules and the result with this logic in mind, it suddenly became clear that the browser insisted on using the largest image, because the calc () function that I use for the first line is:

calc( 100vw * (0.94 * 1.0) * 1.0 ) is a complicated way to write windowWidth * 0.94 .

In other words, the browser assumes that the image is always 94% of the entire width of the window and does not use any other calculations that take into account breakpoints.

In any case, by changing the above rules:

sizes=" (min-width: 1px) and (max-width: 479px) ... (min-width: 480px) and (max-width: 767px) ... (min-width: 768px) and (max-width: 980px) ... "

ensures that the rule applies only to a specific point. Each time the next line evaluates to true, the other lines do not work.

So in the end I went:

<img src="image-fallback.jpg" srcset=" image-300x200.jpg 300w, image-480x320.jpg 480w, image-600x400.jpg 600w, image-960x640.jpg 960w, image-1200x800.jpg 1200w" sizes=" (min-width: 1px) and (max-width: 479px) calc( 100vw * (0.94 * 1.000) * 1.00 ), (min-width: 480px) and (max-width: 767px) calc( 100vw * (0.94 * 0.905) * 0.50 ), (min-width: 768px) and (max-width: 980px) calc( 100vw * (0.94 * 0.850) * 0.33 ), (min-width: 981px) and (max-width: 1088px) calc( 100vw * (0.94 * 0.835) * 0.25 ), (min-width: 1089px) calc( 1089px * (0.94 * 0.835) * 0.25 ), 280px" />

And here is the working example above: Example srcset image (working)

Note: once the browser has uploaded a larger image, it will not want to download smaller ones. This is what the “Update Strength” button is for.

Note # 2: for debugging, I added more source images compared to my original question. I thought it would be easier to keep it simple with two sizes, but I think I would never understand this if I hadn't added a bunch. When I had only 2 images, I thought that he always chose the largest. This is not true, he just did not select the expected image;)

+2
source

Source: https://habr.com/ru/post/1260455/


All Articles