7

Using the LazySizes plugin (https://github.com/aFarkas/lazysizes) I'm trying to build a grid of images, each with an alternate version for smaller viewports. The grid (container) is a simple column/row based percentage based layout.

I'm not quite sure how to declare the images, I keep seeing only the larger versions. I've opted for using high-res images and scaling them down 50% with a max width for the container. Here's a markup sample of the the images:

<img data-sizes="(min-width: 320px) 100vw, (min-width: 768px) 100vw"
  data-src="images/grid/image-small.jpg"
  data-srcset="images/grid/image-small.jpg 720w, images/grid/image-big.jpg 1440w"
  alt="" class="lazyload" />

I only need one breakpoint which is at 768px. The confusing part is the data-sizes attribute. Should I be declaring another size here since the images are high-res or should I just let them have full width?

Added: The generated markup I get when the script initiates:

<img data-sizes="(min-width: 320px) 100vw, (min-width: 768px) 1440px"
  data-src="images/grid/image-small.jpg"
  data-srcset="images/grid/image-small.jpg720w, images/grid/image-big.jpg 1440w"
  alt="" class=" lazyloaded"
  sizes="(min-width: 320px) 100vw, (min-width: 768px) 1440px"
  srcset="images/grid/image-small.jpg 720w, images/grid/image-big.jpg 1440w"
  src="images/grid/image-small.jpg">
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Staffan Estberg
  • 6,795
  • 16
  • 71
  • 107

1 Answers1

8

srcset spec author here.

Well, your current sizes attribute is useless; it just specifies the same size for both breakpoints, and both of them are just specifying the default size anyway.

Why are you trying to do some weird sizing hack? You'll be fighting against what the <img> is trying to do, so whatever you end up with will be hacky.

Just follow the spec: sizes should declare how large the image will be in the page (this defaults to 100vw already, so you can omit it if you already plan on the image being full-width). You can use MQs here if you're doing responsive design and your different layouts need to size the image differently, but if it'll always be the same size, don't complicate things.

Then just declare how large your image is in the `srcset. It looks like you're already doing that, so that's good (assuming that your images really are 720 and 1440 image-pixels wide). The browser will pick the image it wants based on that information.

I'm not 100% sure on how you're planning to use the image, but it sounds like you might be planning on displaying the images as half the width of the screen? In that case, just use sizes=50vw and everything will take care of itself.

(I have no idea how LazySizes works, so if it's doing something weird I can't help you with that.)

Xanthir
  • 18,065
  • 2
  • 31
  • 32
  • 2
    Why doesn’t sizes refer to image size Having it refer to viewport size is great for flexible percentage based images but just adds complexity for fixed sized images – Simon_Weaver Jun 27 '18 at 04:31
  • Ok so I've since found that `media` can be applied to an entire `srcset` which contains 1x, 2x, 3x sizes. Most samples I've found show the media condition being defined within `sizes` which in the world of 1x, 2x, 3x images is very hard to see as useful. (https://html.spec.whatwg.org/multipage/images.html#srcset-attributes) – Simon_Weaver Jun 27 '18 at 08:18
  • `sizes` tells the browser what width the element will be displayed as; when combined with the `w` descriptor in `srcset`, this lets us define a density for images whose displayed size isn't known ahead of time. (If you do know it ahead of time, you can use `x` descriptor instead.) `sizes` accepts MQs because the size might change based on other layout changes due to MQs. The `media` attribute instead tells the browser whether or not to skip the source *entirely* based on an MQ. Totally different functionality. – Xanthir Aug 21 '18 at 20:11
  • 6
    How do you set to sizes="100%" of the img container instead of viewport? in a complex layout with margins paddings it is inviable to define a mediaquery – Vitim.us Jun 09 '20 at 04:32
  • 6
    I spent an hour trying to figure out how to do the most trivial thing with srcset: Just let the browser decide on which image to use based on the layouted size of the image and the pixel density of the display. But turns out the srcset spec is basically useless for saving bandwidth and this is not actually possible - unless you can describe the rendered size of your image based purely on the viewport size - (you'd think the browser already knows how large the image is on the page if width or height is set - but no that would be impossible). – phiresky Jul 17 '20 at 13:40
  • 2
    Having difficulties here as well. `srcset`/`sizes` seem to be pretty useless when having dynamically sized images in a CSS Grid with something like `grid-template-columns: repeat(auto-fit, minmax(500px, 1fr))` – I think it's impossible to apply these rules to `srcset`/`sizes`... – hupf Apr 05 '22 at 10:15
  • @hupf I'm having the same issue. Within a responsive grid, `srcset` seems to fallback to determining image size by the viewport in lieu of its container. – Ryan Prentiss Apr 07 '22 at 06:22
  • My fix was to use a `` element with multiple `` elements than can each define a media query and its own `srcset`. Like this I was able to at least approximate to the specific page/grid I was optimizing the images for. But it is not at all an optimal solution – IMO it is a complete fail, that these APIs relate to the full viewport width instead of the element's width... – hupf Apr 11 '22 at 09:47
  • `Just follow the spec: sizes should declare how large the image will be in the page` -- This can be (for all intents and purposes) unpredictable in some cases (flex layouts with content that isn't hard-coded?) Is there a solution for this? – Luke A. Leber Jan 23 '23 at 19:42