7

I've been scouring responsive image posts and examples, but I can't find a solution. It seems like this should be easy, I might just be missing something: How would I serve the appropriate image size based on container width rather than screen width?

I.e. I have a desktop screen, 1980px wide, but a flex container that's 1/3 of the screen, so the max image size would only need to be 660px wide, so it should show the 800w image. But srcset will only go off of the screen size, so even if I'm displaying thumbnails, it will load the 1200w image. Is there a way to do this dynamically. i.e. still use flebox and dynamic widths, but have it serve the appropriate size based off of container width not screen width? Any help would be greatly appreciated, thanks!

<div class="flex justify-center w-1/3 mx-auto">
<img
  srcset=" srcset="size-1.jpg 400w,
  size-2.jpg 800w,
  size-3.jpg 1200w,"
  sizes=" (min-width: 1200px) 1200px, (min-width: 800px) 800px, 400px"
/></div>
Alteredorange
  • 556
  • 1
  • 6
  • 23
  • A bit late but maybe helpfull to others: [Responsive Images Guide](https://www.smashingmagazine.com/2014/05/responsive-images-done-right-guide-picture-srcset/) – aProgger Oct 01 '21 at 14:35

2 Answers2

4

You could mathematically describe how big the image would be displayed inside the sizes attribute. You can use calc() to achieve more complex calculation, for example if there is margin between your images and you want to be precise or if the container is not full width.

Example without calc():

<div class="flex justify-center w-1/3 mx-auto">
  <img
    srcset="size-1.jpg 400w,
    size-2.jpg 800w,
    size-3.jpg 1200w"
    sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 33.33vw"
  />
</div>

Example with calc():

<div class="flex justify-center w-1/3 mx-auto">
  <img
    srcset="size-1.jpg 400w,
    size-2.jpg 800w,
    size-3.jpg 1200w"
    sizes="(max-width: 600px) calc(100vw - 30px), (max-width: 1200px) calc(50vw - 30px), calc(33.33vw - 30px)"
  />
</div>
alex-schuster
  • 102
  • 1
  • 7
  • 1
    Hmm that would work for something non-responsive, but I'd have to do something janky to get it to work with mobile (which might be 100vw) and desktop (which might be 33vw). It's crazy there's no easy solution, but I guess bandwidth isn't first priority these days. – Alteredorange Apr 19 '20 at 02:17
  • 1
    Responsive layouts are possible as well: `sizes="(max-width: 600px) 100vw, calc(100vw / 3)"` – alex-schuster Apr 19 '20 at 10:57
  • Ah perfect, that's exactly what I needed, thanks for the help! – Alteredorange Apr 20 '20 at 15:06
-2

Why do you want to use 3 different source files? Are they just different sizes of the same image or do you have completely different images you want to show on each container size?

If all you want is for the picture to fit its container you can handle that by just setting one source file and using the CSS property width: 100% Pixels get translated into a unit of distance like inches*. By setting the width of the image in units of % it automatically sizes the image relative to the width of its parent element, in your case the <div>.

There are other units you can use for width besides % and px. Check out this article Viewport Units.

If you actually want to use three different images depending on container size then you will need to have all three sources listed as you currently do.

This article should help: Responsive Images This excerpt from it in particular:


    <img
      sizes="(min-width: 400px) 80vw, 100vw"
      srcset="examples/images/small.jpg 375w,
              examples/images/big.jpg 1500w"
      alt="…"
    >

The information in the markup above gives the browser what it needs to figure > out the best image for it. The browser knows 1) it’s own viewport size and 2) > it’s own pixel density.

Perhaps the browser viewport is 320px wide and it’s a 1x display. It now also knows it will be displaying this image at 100vw. So it has to pick between the two images provided. It does some math.

375 (size of image #1) / 320 (pixels available to show image) = 1.17 1500 (size of image #2) / 320 (pixels available to show image) = 4.69

1.17 is closer to 1 (it’s a 1x display), so the 375w image wins. It’ll try to > not go under, so 1.3 would beat 0.99, as far as I understand it.

* Technically pixels are a measure of an angle, like degrees and radians, and are based on an assumption about the distance the screen is being viewed from.

Nigel Wilson
  • 17
  • 1
  • 1
  • 11
  • It's purely a bandwidth consideration. All images are the same. I understand how to fill the container any way I want, I just want to send the minimal amount of data needed. – Alteredorange Apr 18 '20 at 23:01
  • examples for bandwidth consideration: Google (and I with my mobile 100MB data volume) will punish you for displaying a 1920w image on a 420w device. Why? Because a 1920w jpg has around 200 - 500kb, depending on the content. If you scale it down with width: 50%; you dont scale the size down! Thats where srcset takes place. Google and I will be happy! – aProgger Oct 01 '21 at 14:29