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