Explain what grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) does, and how the layout changes if auto-fit is replaced with auto-fill.
answer
- the browser counts the columns for you
- the minimum is the real breakpoint
- empty tracks: keep them or drop them
- auto-fit collapses empties to zero
- identical once every track is filled
basics
~20 sIt builds a responsive grid with no media queries: the browser fits as many 200px-minimum columns as the container allows and stretches them to share the leftover space. auto-fit collapses tracks left empty, so few items stretch across the full width; auto-fill keeps those empty tracks, so items stay at their column width.
solid answer
~50 sThe `repeat(auto-fit, …)` form asks the browser to compute the repetition count itself: it fits as many tracks of at least 200px as the container width allows, counting the gaps, then the `1fr` maximum lets those tracks share the remaining space so there is no ragged right edge. Resize the container and the column count changes on its own — that is the whole "responsive without media queries" trick. The difference from `auto-fill` shows up only when there are fewer items than the container could hold: `auto-fill` generates the full set of tracks and leaves the surplus ones empty but still occupying space, so two items in a five-track row stay narrow on the left. `auto-fit` generates the same tracks, then collapses every empty repeated track to zero — along with its gutters — so the two remaining items absorb everything and stretch across the full width. If item count always exceeds the track count, the two keywords render identically.
code
css · 11 lines.gallery {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
}
.listing {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 16px;
}go deeper
Be able to read the declaration aloud and say what each part does: repeat with auto-fit picks the column count, the 200px minimum decides how many fit, the 1fr lets them stretch. Naming it as the no-media-query responsive grid is enough.
Explain the counting arithmetic including gaps, and state the real difference precisely: both compute the same count, but auto-fit collapses empty repeated tracks and their gutters to zero. Note that with a full grid the two render identically.
Show you choose deliberately — auto-fit when a sparse row must fill, auto-fill when card rhythm must survive a filtered list — and cite the two-results-become-giant-cards failure. Mention the definite-size requirement and the min(200px, 100%) guard for narrow containers.
Argue the strategy: content-derived minimums replace device breakpoints, so a component stays correct wherever it is placed and the breakpoint list stops growing. Be ready to say where that breaks down and a container query or an explicit track list is the honest answer.
## What the declaration is asking for ```css .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; } ``` Three pieces are doing three different jobs: - `repeat(auto-fit, …)` — do not tell the browser how many columns; let it work out how many fit. - `minmax(200px, …)` — a column is never narrower than 200px, which is what determines how many fit. - `…, 1fr` — once the count is fixed, let the columns share the leftover space so the row ends flush. Drop the `1fr` and use `minmax(200px, 200px)` and you get rigid 200px columns with a ragged gap at the right edge. Drop the `200px` and there is nothing for the repetition count to be computed from. ## How the repetition count is computed The browser takes the grid container's inner size in that axis, and finds the largest whole number of tracks that fit when each track is at its **minimum** size and every gutter between them is included. In a 1000px container with `gap: 16px` and a 200px minimum, five tracks need 5 × 200 + 4 × 16 = 1064px — too much — so four tracks are generated (4 × 200 + 3 × 16 = 848px). The remaining 152px is then handed to the `1fr` maxima, giving four columns of 238px. The count is always at least one. Two constraints follow from needing that arithmetic to be possible: - The container's size in that axis must be definite (or have a definite max size); with an indefinite size the browser cannot count, and the repetition collapses to one track. - The auto-repeated track needs a definite minimum. `minmax(200px, 1fr)` is fine because 200px is definite; an intrinsic minimum such as `minmax(min-content, 1fr)` is not allowed in an auto-repeat. ## The actual difference between the keywords Both keywords compute the same repetition count. Then: - **`auto-fill`** stops there. Every generated track exists, occupies at least its minimum, and — because the maximum here is `1fr` — also takes a share of the free space. Tracks with no items in them are still real tracks holding real width. - **`auto-fit`** does one more step: after items are placed, every *empty* repeated track is collapsed to a zero-sized track, and the gutters on either side of a collapsed track collapse with it. The surviving tracks then re-run the flexible sizing and soak up all the space. So with three items in a container that fits five 200px tracks: - `auto-fill` → three items sit at roughly one fifth of the width each, with two empty fifths of dead space to the right. - `auto-fit` → three items stretch to roughly one third of the width each and fill the row. With six items in the same container both produce identical output, which is why so many people believe the keywords are interchangeable: on a full grid they are. ## Choosing between them Pick `auto-fit` when items should always fill the row — marketing card grids, image galleries, dashboards where a half-empty row looks broken. Pick `auto-fill` when column rhythm matters more than filling: a product listing where a single result should stay card-sized rather than ballooning to 1200px wide, or a layout that must line up with a sibling grid above it. "Two search results become two enormous cards" is the classic bug report caused by reaching for `auto-fit` reflexively. ## Choosing the minimum The minimum is the only real design decision here, because it *is* the breakpoint. Derive it from the narrowest width at which the card's content is still readable, not from a device size. One caveat: if the container ever gets narrower than the minimum, a single track still holds its 200px floor and overflows. `minmax(min(200px, 100%), 1fr)` is the common guard — the floor becomes the full container width when the container is smaller than 200px — and the `min()` function is well supported in current browsers. ## What it does not do This pattern controls column count and width only. It does not equalise row heights across cards, it does not reorder anything, and it does not know what is inside the cards — a card with a wide unbreakable element can still push its track past its share, because the flexible maximum has no say over content-driven minimums.
- When do auto-fit and auto-fill produce exactly the same rendering?Whenever there are at least as many items as the computed track count, so no repeated track is left empty. Since auto-fit's only extra step is collapsing empty tracks, a full grid gives it nothing to collapse. That is why the difference is invisible on a demo with twelve cards and suddenly obvious when a filter narrows the list to two.
- Why does repeat(auto-fill, minmax(200px, 1fr)) sometimes render as a single column even in a wide layout?Because the repetition count needs a definite size in that axis to divide. If the grid container's inline size is indefinite — for example an inline-size-shrinking context — the browser cannot compute how many tracks fit and falls back to one repetition. Giving the container a definite width, or a definite max-width, restores the expected count.
- How would you stop the layout from overflowing when the container is narrower than the 200px minimum?Make the floor adaptive: `repeat(auto-fit, minmax(min(200px, 100%), 1fr))`. The `min()` function makes the minimum equal to the container width whenever that is under 200px, so the single track shrinks with the container instead of holding 200px and overflowing. `min()` is widely supported in current browsers.
saying these in an interview costs you the question
- Says auto-fit makes more columns than auto-fill
- Claims the two keywords are simply interchangeable
- Thinks the browser ignores gap when counting tracks
- Believes auto-fit works without a definite minimum
- Says this pattern equalises card heights too