In CSS Grid, how do the track sizes min-content, max-content, and fit-content(400px) differ when used in grid-template-columns?
answer
- wrap as hard as possible
- no wrapping at all
- the same idea with a ceiling
- fit-content clamps at its argument
- none of them take free space
basics
~20 smin-content sizes a column to the narrowest width its content can take when it wraps as hard as possible; max-content sizes it to the content laid out on one line with no wrapping; fit-content(400px) behaves like max-content but is capped at 400px, wrapping beyond that.
solid answer
~50 sAll three are content-based, meaning the track's width comes from what is inside it rather than from the container. `min-content` gives the smallest width the content can occupy while still wrapping — for text that is the longest unbreakable word. `max-content` gives the width the content would take with no wrapping at all, so a long paragraph produces one enormous column that usually overflows. `fit-content(400px)` is the clamp between them: it behaves like `max-content` until the content would exceed 400px, then holds at 400px and lets the content wrap; formally it resolves to `min(max-content, max(auto-minimum, 400px))`. None of the three is flexible, so they do not absorb leftover free space — any remainder stays free and is disposed of by content alignment. The everyday uses are `max-content` or `fit-content()` for a label or button column that should hug its text, and `min-content` for a track that must give the rest of the layout as much room as possible.
code
css · 11 lines.demo {
display: grid;
grid-template-columns: min-content fit-content(400px) max-content;
gap: 12px;
}
.form {
display: grid;
grid-template-columns: max-content 1fr;
gap: 12px 16px;
}go deeper
Know the three in one line each: min-content is as narrow as wrapping allows, max-content is one unwrapped line, fit-content(x) is max-content capped at x. Recognising max-content as the reason a column got enormous is the practical win.
Explain min-content and max-content contributions properly, unpack fit-content() as a clamp between them, and state that none of these tracks is flexible so leftover space stays unused. Contrast them with auto, which alignment can stretch.
Reach for max-content 1fr as the maintenance-free label-and-field pattern, and know when to cap with fit-content() so a long string cannot eat the layout. Be able to say that intrinsic sizing costs extra layout work and why that matters on very large grids.
Decide when content-driven tracks belong in shared components at all: they make a layout self-adjusting to copy and localisation, but they also make one long translated string a layout risk. Owning that trade-off — caps, wrapping rules, or fixed tracks — is the call to defend.
## Content-based sizing in one picture Given the text "Grid track sizing explained", the three sizes are: - **max-content** — the width of the whole phrase on one line, nothing wrapped. - **min-content** — the width of "explained", the longest single word, with the phrase wrapped at every opportunity. - **fit-content(<limit>)** — max-content while that fits under the limit, otherwise the limit. Every intrinsic size in CSS is one of the first two, or a clamp between them. Grid simply lets you name them as track sizes. ```css grid-template-columns: min-content fit-content(400px) max-content; ``` ## min-content A `min-content` track takes the largest **min-content contribution** among the items in it. For text that is the longest unbreakable run: a long word, a URL, a hash. For a replaced element such as an image it is that element's own intrinsic minimum. The track is as narrow as it can be without content being forced to overflow. Use it when a track must not compete for space — an icon column, a checkbox gutter, a label that should stay as tight as possible so a neighbouring `1fr` track gets everything else. ## max-content A `max-content` track takes the largest **max-content contribution**: the width of the content with wrapping suppressed. This is the right size for a column of short strings — a button, a date, a numeric total, a nav item — where wrapping mid-phrase looks broken. It is also a foot-gun. A `max-content` column containing a paragraph is as wide as the whole paragraph on one line, and grid will not shrink it back, so the grid overflows its container. "My column is a mile wide" is nearly always a `max-content` (or `auto` under content pressure) track holding prose. ## fit-content() `fit-content()` takes a length or percentage argument and gives you max-content sizing with a ceiling. Its resolved value is `min(max-content, max(auto-minimum, argument))`, which unpacks as three rules: 1. If the content's max-content width is under the argument, the track is exactly that content width — it hugs, just like `max-content`. 2. If the content is wider, the track stops at the argument and the content wraps inside it. 3. The automatic minimum still applies, so an unbreakable word wider than the argument still forces the track past it. That makes `fit-content(400px)` the honest answer to "hug the content, but never get ridiculous", which is what people usually mean when they reach for `max-content`. Note the argument must be a length or percentage — `fit-content(min-content)` is not a thing, and the bare keyword `fit-content` used as a track size behaves as `auto`. ## How they relate to `auto` An `auto` track is close to `minmax(min-content, max-content)`: it hugs its content between the two intrinsic bounds. The distinguishing detail is that `auto` tracks — and only `auto` tracks — can be stretched by content alignment when there is leftover space, whereas a `max-content` track never grows past its content. So `auto` is the forgiving default, and `max-content` is the promise that the track will never be wider *or* narrower than its content wants on one line. ## They are not flexible None of these tracks participates in free-space distribution. In `grid-template-columns: max-content max-content`, a wide container leaves a chunk of space unused at the end of the row rather than being shared out. That is a feature when you are building a toolbar or a form, and a surprise when you expected the row to fill. If you want hugging *and* filling, mix them: `max-content 1fr` hugs the first column and gives everything left to the second. ## A worked example ```css .form { display: grid; grid-template-columns: max-content 1fr; gap: 12px 16px; } ``` The label column is exactly as wide as the longest label — no manual `width` to maintain when the copy changes — and the input column takes the rest. Swap the first track to `fit-content(200px)` and the same layout survives someone adding a 40-word label: it caps at 200px and wraps instead of eating the form. ## Performance note Intrinsic sizing asks the browser to lay content out more than once to discover its min-content and max-content widths, so large numbers of intrinsic tracks over large subtrees are measurably more expensive than fixed or flexible tracks. It is rarely the first thing to optimise, but it is a real reason to prefer `minmax(<length>, 1fr)` over content-based tracks in very large grids.
- How does an auto track differ from a max-content track?An auto track sits between the content's min-content and max-content sizes rather than pinning to the maximum, and it is the only track type that content alignment can stretch when there is leftover space. A max-content track is fixed at its unwrapped content width — never narrower under pressure, never wider when space is spare.
- Why might a max-content column overflow the grid container?Because it is sized from content with wrapping suppressed and has no upper bound. Put a paragraph in it and the track is as wide as that paragraph on one line, which can easily exceed the container. The track sizing algorithm has no mechanism to pull a max-content track back down, so the grid simply overflows. fit-content() with a sensible cap is the usual remedy.
- What does fit-content(400px) do when the content contains a single unbreakable 600px-wide word?The track ends up 600px wide, not 400px. The automatic minimum still applies underneath the clamp, so content that cannot wrap below the cap pushes the track past it. If you need the 400px ceiling honoured absolutely, pair it with a wrapping rule such as overflow-wrap: anywhere, or clip the item's overflow.
saying these in an interview costs you the question
- Says min-content wraps text at every character
- Thinks max-content is capped by the container
- Treats fit-content() as a synonym for auto
- Expects content-based tracks to absorb leftover space
- Passes a keyword like min-content into fit-content()