How to debug responsive images' srcset & sizes, like which media condition applies?
Asked Answered
D

1

9

So yet again I find myself pulling my hair over responsive images. The CMS gives me its srcset, I build a simples sizes attribute, I check the currentSrc by hover-fumbling over the attribute in Dev Tools– wrong Src! Go to 10, change a media condition maybe, save, reload, hover, repeat until it kinda works. Hope it will never fail for other images.

There must be a better way to do this? Considering that Firefox is still better than Chrom* at debugging Webfonts and that only today I have found Add device pixel ratio in Chrome's Dev Tools, I wonder if I'm overlooking something. I know of & have used placeholder images, but they can be a pain to set up and they can't tell me

  • is the sizes attribute syntactically correct?
  • how many device pixels does the browser consider the image to be in the current viewport? How many "srcset w-pixels" is that?
  • and most importantly: which media condition matches the current viewport? Why?

EDIT: came up with this example, hope it helps:

<img
  src="foo.jpg"
  sizes="(max-width: 599px) 100vw, ((min-width: 600px) and (max-width: 1000px)) 33vw, 300px"
  srcset="foo_a.jpg 300w, foo_b.jpg 768w" />

Viewport at 650px, device-pixel-ratio 1.
DevTools tells me:

currentSrc == "foo_b.jpg"

Why? Which condition is this? What does 33vw end up as? 650px*33/100? How does it relate to 300w? How is this closer to 768w?
Please note that I'm not really asking about these specific values, but a general workflow.

EDIT2: I am probably asking for a Dev Tools feature (or extension) that would tell me, in this case:

  1. Viewport 650px
  2. matches ((min-width: 600px) and (max-width: 1000px))
  3. 650px @ DPR 1.0 = 650w
  4. => 33vw = 650w*33/100 = 214.5w
  5. closest src = foo_a.jpg 300w
  6. BUT, I have foo_b.jpg in cache
  7. pick foo_b.jpg
Dacron answered 12/3, 2019 at 16:8 Comment(5)
Ok having read further up on the sizes attribute, I was totally wrong! The reason you are probably seeing foo b is because it is the image for larger window sizes - once that image has been loaded and cached by the browser, it will always be used, even if the browser is resized to the smaller resolutionResponsion
@Responsion :) yes, it's complicated.Dacron
That's why I prefer the picture tag - very simple and does what it says on the tin!Responsion
@Pete, unfortunately, unapplicable (although I suspect that it can't be that different, once you have complicated cases). Re: caching: I had disabled cache & force-cleared it, but had missed that it sneakily repopulates when the same images appears elsewhere on the page (and out of your viewport...) It would be helpful if the browser said: "I'm using this very src because of cache (and not because your sizes is wrong)"Dacron
Chrome dev tools tells you if an image is from chache or not. When you check Network > Img. The Size column will mention all images loaded from cache. You need to reload the page to start a recording.Vas
L
1

is the sizes attribute syntactically correct?

In your case no. Outer parens on ((min-width: 600px) and (max-width: 1000px)) appear to be extra.

how many device pixels does the browser consider the image to be in the current viewport? How many "srcset w-pixels" is that?

If you know your device pixel ration (DPR), you can use that value to divide real image width (w value in srcset) to get pixel width that will image occupy on screen.

Browsers know this from srcset and sizes attributes you provided and take it into account when deciding which image to use.

and most importantly: which media condition matches the current viewport? Why?

Media queries in sizes attribute work exactly same as CSS media queries. So first valid media query, reading from left to right will be applied. Funny thing browser does (Chrome at least), if one query between set of commas is invalid it won't invalidate whole sizes attribute, just that query.

You can test this by applying those same set of media queries in CSS, like so (note I'm using Sass):

body {
   @media (max-width: 599px) {
      &:before { content: "max-width: 599px"; }
   }
   @media (min-width: 600px) and (max-width: 1000px) {
      &:before { content: "(min-width: 600px) and (max-width: 1000px)"; }
   }   

In case of your second query, my linter reported invalid format until I removed outer parens. That's how I knew about your first point.

My test example: https://codepen.io/teodragovic/pen/eXjPoz
Good reference article: https://ericportis.com/posts/2014/srcset-sizes/

Lager answered 19/3, 2019 at 11:32 Comment(5)
Some good input, although still a hacky mess that feels like the days of pre-firebug debugging, but probably as good as it gets as of today :) What's that linter you used? Note: media conditions are a subset of media queries, so not exactly same, and, btw, according to spec, the extra parens should be fine, unless I'm misinterpreting something... sigh.Dacron
Huh, can it lint HTML? Or did you extract the attributes & rebuild the CSS? Do you remember the specific csslint rule that this broke?Dacron
I meant that I extracted your attribute into CSS snippet I posted and then error appeared. It throwed (max-width: 1000px) isn't a valid CSS value. I don't know of HTML linter that would validate srcset or sizes attribute.Lager
One other thing: img media conditions don't match the viewport (I mean they do, but not in the way you expect them). You are describing what the applied image width (ie. after css loads) will be depending on the viewport. Combined with list of images in srcset and other data, browser decides what image to use. Those rules/logic vary depending on the browser itself and are not exposed anywhere AFAIK.Lager
Ah, yes, thanks. csslint gives me Expected IDENT / Unexpected token '(' for the extra parens, stylelint (via web demo) says Unexpected unknown media feature name "(min-width". And, "are not exposed anywhere" is exactly the problem. I think I understand all the rules and the algorithm (the extra parens were an artifact of trial&error), but sometimes "The user agent selects any one of the available sources at its discretion." (MDN), which could be exposed in Dev Tools. Time for a feature-request, I guess...Dacron

© 2022 - 2024 — McMap. All rights reserved.