CSS Grid auto-fit Calculator
repeat(auto-fit, minmax(240px, 1fr)) is in every modern stylesheet, and almost nobody can say at what width it stops being three columns. Here is the exact answer, along with every breakpoint it creates that your CSS never mentions.
The breakpoints you did not write
The appeal of auto-fit is that it replaces a pile of media queries with one line. What is easy to miss is that it does not remove the breakpoints — it just stops you being able to read them. The layout still changes at specific widths; those widths are now emergent from three numbers rather than written down anywhere.
The rule itself is simple. The browser fits as many tracks of the minimum width as it can, with a gap between each pair, so n × min + (n − 1) × gap ≤ container. The gaps are the part people drop: three 240px columns need 768px, not 720px.
That gives a ladder of implicit breakpoints — 240, 504, 768, 1032, 1296 for a 240px minimum and a 24px gap — and a layout that falls apart at one of them is a layout that broke at a width nobody picked and nobody tested. Seeing the ladder is usually the whole fix: nudge the minimum so the changes land where your content wants them to.
The other half is minmax()’s first argument, which is a hard floor rather than a suggestion. A 240px minimum will not shrink on a 320px screen; it overflows and the page scrolls sideways. minmax(min(240px, 100%), 1fr) is the fix, and it is worth knowing before a phone shows you.
Frequently Asked Questions
How many columns does repeat(auto-fit, minmax(240px, 1fr)) give me?
As many as fit at the minimum width, counting the gaps. The browser solves n × min + (n − 1) × gap ≤ container, which works out to n = floor((container + gap) ÷ (min + gap)). With a 240px minimum and a 24px gap, three columns need 768px and not 720px, because two gaps sit between them. That 48px is exactly the sort of difference that makes a layout collapse one breakpoint earlier than you expected.
What is the difference between auto-fit and auto-fill?
Both create the same number of tracks. The difference is what happens to tracks with nothing in them: auto-fill keeps them at their minimum width, holding space open, while auto-fit collapses them to zero so the 1fr maximum lets your real items stretch across the whole row. If you have at least as many items as tracks, the two are indistinguishable — which is why the choice looks arbitrary right up until a grid is half empty.
Why doesn't my last row stretch to fill the width?
Because auto-fit collapses empty tracks, not empty cells, and this catches almost everyone out. Nine items across four columns leaves one item alone on the last row — but all four tracks are occupied, by the items on the rows above. No track is empty, so auto-fit has nothing to collapse and that last item stays one column wide. If you want the last row to fill, you need a different mechanism: grid-column: 1 / -1 on the last item, or flexbox, which grows items rather than tracks.
Why does my grid break at a width I never wrote a media query for?
Because auto-fit generates its own breakpoints and they appear nowhere in your stylesheet. Every width at which the column count changes is an implicit breakpoint — with a 240px minimum and a 24px gap they land at 240, 504, 768, 1032 and 1296px, none of which is a width you chose or tested. Knowing where they are is usually enough to fix the problem, either by nudging the minimum so the changes land somewhere sensible or by testing at the widths that actually matter.
Why does my grid overflow on small screens?
Because the first argument to minmax() is a hard floor. A 240px minimum means the track will not go below 240px for any reason, so on a 320px screen with container padding the grid overflows rather than shrinking, and the page scrolls sideways. The standard fix is minmax(min(240px, 100%), 1fr): the inner min() lets the floor itself drop to the container width when the container is the smaller of the two, so the column gives way instead of pushing out.
Should I measure the container or the viewport?
The container, always — the grid only ever knows about the space it has been given. If the page has 2rem of padding on each side, a 1280px viewport gives the grid 1216px, and at a 240px minimum with a 24px gap that is the difference between four columns and four columns with 16px to spare. Include padding, borders, and the scrollbar if the platform draws one that takes layout space, because the browser does.