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%;
}

6
  • 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. Commented Jun 10, 2023 at 13:36
  • Did you come up with a configurable solution for this challenge? Commented Feb 12, 2024 at 4:58
  • Short answer: no. Slightly longer answer, is that I think my question was next to impossible to answer because there are so many different screen resolutions. I suspect most people just settle on a range of image resolutions and offer those to the browser and let it get on with it. The problem then becomes, which image resolutions to offer; I found this answer useful for this: webmasters.stackexchange.com/a/132318/102751 Commented Feb 14, 2024 at 15:06
  • Also FYI, I've given up on changing the root font-size. The reason for this is that media-queries/conditions are parsed before the CSS is downloaded so any attempt to change font-size is ignored in these cases... thus, I found it simpler it just stick with 1rem == 16px. Commented Feb 14, 2024 at 15:06
  • If/when I get a chance, I will try to post a more complete update on this, but I must admit to getting side-tracked and now not quite remembering what I was attempting to do at the time!! :O Commented Feb 14, 2024 at 15:07

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.