1

I have a CSS grid with a fluid layout of repeating columns minmax(33.8rem, 1fr).

The grid container has a max-width: 140rem applied, so it will show a maximum of 4 columns. The grid container is centred using margin: 0 auto.

Each grid cell holds a "card" with an image and some text underneath.


My question is, how do I make each image use a resolution that is near to the "ideal" size?


The problem I have is that whilst I've set the :root font-size to 62.5% so that 1rem (usually) equals 10px, I still don't know exactly how wide each grid column will be.

For most mobile phones, a single-column will be shown. This could be less than 33.8rem but will likely be more (1fr) which could be just under 2 x 33.8rem = 66.7rem.

The following <img> tag works reasonably well:

<img alt=""
  src="https://placehold.co/208x130.png"
  sizes="(max-width: 715px) 100vw,
         (max-width: 1069px) 50vw,
         (max-width: 1399px) 33vw,
         25vw"
  srcset="https://placehold.co/320x200.png 320w,
          https://placehold.co/560x350.png 560w,
          https://placehold.co/640x400.png 640w,
          https://placehold.co/704x440.png 704w,
          https://placehold.co/800x500.png 800w,
          https://placehold.co/960x600.png 960w,
          https://placehold.co/1280x800.png 1280w"
/>

The sizes attribute uses breakpoints that are just under 2-col, 3-col and 4-col, and use vw percentages... so anything under 2-col uses 100vw and ends with 25vw for the 4-col layout. (I'm aware that I can use calc() to subtract my padding etc from 100vw; not done here for simplicity!)

This seems to work well and will select the correct image size even on devices with DPR > 1 (so most mobile devices).

However, when I use a desktop-type resolution (say 1920x1080) with a DPR of 1, it'll use the 4-col layout. At this point, it decides that 25vw is the image size it should use and in this case I know it should choose the 320w image because the 4-col layout is constrained by the max-width of the grid container. But it doesn't - it chooses a larger image! This (I believe) is because 25% of 1920 = 480px (I'm assuming a maximised browser window), but the grid is centred and where that's irrelevant with less than 4 columns, once the grid hits it's max-width, the centring works and so images could be smaller.

I could change the sizes attribute so that the default is 320px, but then it'll request 320px images even on devices with higher DPR which isn't good either.

  sizes="(max-width: 715px) 100vw,
         (max-width: 1069px) 50vw,
         (max-width: 1399px) 33vw,
         320px"

Is there any way to resolve this?


The main bits of the CSS are here (these are after a CSS reset):

:root { font-size: 62.5%; }
body  { font-size: 1.6rem; }
main  { margin: 0 auto; }
.grid {
  display: grid;
  grid-template-columns: repeat( auto-fill, minmax(33.8rem, 1fr) );
  gap: 1.6rem;
}
.card {
  background-color: #f9f9f9;
  padding: 0.8rem;
  border: 1px solid #bacdd8;
}
.card img {
  width: 100%;
}

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
Peter Ryan
  • 214
  • 1
  • 9
  • 1
    I'm still playing with this, but I've actually tested using a specific pixel width in the sizes attribute and thus far it _appears_ that the browser then multiplies this by DPR to get the ideal image width. But I am still testing right now... I'll post an update or answer ASAP but it might be a day or three. – Peter Ryan Jun 10 '23 at 13:36

0 Answers0