Fluid columns, max 3

🤑
💀
🧠
🥷
🪢
💾

I wanted a grid of max three columns, which would shrink to two or one column if needed. I could never solve it in a single grid-template, and resorted to media queries.

Recently, I picked up a neat trick from Chris Coyier:

Neat!
grid-template-columns: repeat(auto-fit, minmax(min(100%, max(12rem, 100%/3)), 1fr));

This is the way. Much better than querying screen width, this responds to the width of the grid. You don’t even need a container query. Neat!

Also neat: In min() and max(), you can do maths without calc(). I didn’t know that.

Complicating factor

If you have a grid-gap, the grid above will max out at two columns, not three.

This happens because three columns sized 100%/3 will not fit when there are gaps between them. You can work around it with 100%/4, as if you wanted four columns. (Chris Coyier did.) You will get three, as long as the gap is there to force it back down.

Alternatively, and perhaps neater, subtract one gap: 100%/3 - 1rem

In complex formulas like this, I like to make my intention clear by using variables.

--max-columns: 3;
--min-column-width: 12rem;
--gap: 1rem;

display: grid;
grid-template-columns: 
  repeat(
    auto-fit,
    minmax(
      min(100%, max(var(--min-column-width), 100%/var(--max-columns) - var(--gap))),
      1fr));
grid-gap: var(--gap);