Intrinsic Sizing (fit-content, min-content, max-content)
Alongside fixed lengths (200px) and percentages (50%), CSS offers keyword sizing values that ask an element to size itself based on its own content rather than its container. These intrinsic sizing keywords work for width, height, and as track sizes inside Grid.
The Three Values Compared
Value | Behavior |
|---|---|
| The smallest size the content can be without overflowing — for text, this is the width of its longest unbreakable word. |
| The size the content would take with no wrapping constraint at all — for text, the full length of the content laid out on one line, ignoring the container width. |
| A clamped hybrid: behaves like the available space, but never grows past |
.min { width: min-content; }
.max { width: max-content; }
.fit { width: fit-content; }
.fit-300 { width: fit-content(300px); } /* capped hybrid */Worked Example: Watching the Difference
<div class="box min-content">A fairly long sentence of button text</div> <div class="box max-content">A fairly long sentence of button text</div> <div class="box fit-content">A fairly long sentence of button text</div>
.box {
border: 2px solid #4a90d9;
padding: 8px;
margin-bottom: 8px;
}
.min-content { width: min-content; }
/* Wraps at every possible line break — becomes as narrow as its
longest unbreakable word allows, growing tall instead of wide. */
.max-content { width: max-content; }
/* Never wraps at all (unless it hits the viewport) — becomes exactly
as wide as the full sentence needs to render on one line. */
.fit-content { width: fit-content; }
/* Behaves like "auto" up to max-content's width, then would shrink
toward min-content if the surrounding container got tighter. */In a wide container, min-content produces a very narrow, tall box (wrapping after nearly every word), max-content produces a wide box exactly as wide as the unwrapped sentence, and fit-content looks identical to max-content here because there's plenty of room — the difference only shows up once the container gets tight enough to force fit-content to shrink.
Practical Use Case: A Sidebar Sized to Its Longest Word
.nav-sidebar {
width: min-content; /* exactly as wide as its longest unbreakable label */
}<nav class="nav-sidebar"> <a href="#">Home</a> <a href="#">Documentation</a> <a href="#">Settings</a> </nav>
min-content here gives the sidebar exactly the width needed to avoid breaking "Documentation" mid-word — no wider, no narrower — which is a cleaner outcome than guessing a fixed pixel width by eye.
Practical Use Case: A Button Sized to Its Text
.button {
width: fit-content; /* exactly as wide as the label, never more */
padding: 8px 20px;
display: block; /* fit-content on a block-level element needs display: block/inline-block/etc. */
}Without any width set, a <button> already sizes to its content by default because buttons aren't block-level. But applying fit-content to a genuinely block-level element (a <div> acting as a button, or a block-level link) is exactly how you get that same "hug the content" sizing without switching its display type to inline-block.
Intrinsic Sizing Inside Grid Tracks
.grid {
display: grid;
/* first column exactly as wide as its widest content ever needs,
second column takes the rest */
grid-template-columns: max-content 1fr;
}min-content— use when a column or box should be as narrow as its content structurally allows (labels, sidebars, vertical nav).max-content— use when you want an element exactly as wide as its content wants, ignoring the container (rare on its own; more common as a Grid track size).fit-content— use for the common "hug my content, but don't overflow the available space" case, like auto-sizing buttons or badges.