I am looking for a way to automatically generate a grid, that always fills the available space, while shrinking the items until another item can be added.
Most responsive grid implementations use something link this:
grid-template-colums: repeat(auto-fill, minmax(120px, 1fr));
This works fine, except, that it uses the minimum value as the default image size, which results in interpolation of the images inside the grid. I want to do the opposite — set a max-width and shrink the images if necessary.
Let’s say my grid items should have a max-width of 400px. Here are some of the values, that I want to get:
400px available space: One image with a width of 400px
402px available space: Two images with a width of 201px
800px available space: Two images with a width of 400px
and so on …
Essentially I want to clamp my image between 200px and 400px and always use the biggest value possible. I guess I need something like this:
min(max(200px, 1fr), 400px)
The only way I was able to achieve this so far, was by generating some media queries.
/* This example adjusts items to a max-width of 400px with a 10px grid-gap.*/
@media (min-width: 401px) {
.grid {
grid-template-columns: repeat(auto-fill, calc((100% - 10px) / 2));
}
}
@media (min-width: 811px) {
.grid {
grid-template-columns: repeat(auto-fill, calc((100% - 20px) / 3));
}
}
I have written a Sass mixin to make this process more flexible, but this solution comes with some draw-backs:
- You have to generate an arbitrary amount of queries in order to handle multiple screen sizes, which probably results in dead-code
- You have to know the available space of the grid container for the media queries (or the used space to calculate the available space)
I am looking for a way that does not have these drawbacks.
Edit:
Here is a CodePen of my current code. It should be easier to understand what I want to do, if you play around with it.