min-content sizing for buttons
Set width: min-content on a button to shrink it to exactly fit its label text — useful for inline button groups where labels vary in length.
Quick implementation
/* Button sized to its label */
.btn-min {
width: min-content;
white-space: nowrap; /* prevent label from wrapping */
padding: 0.5rem 1rem;
border-radius: var(--radius);
border: 1px solid oklch(0.52 0.22 265);
background: oklch(0.52 0.22 265 / 0.15);
color: oklch(0.72 0.19 265);
cursor: pointer;
font: inherit;
font-weight: 600;
}
/* In a flex row, prevent flex from shrinking the button */
.btn-group {
display: flex;
gap: 0.75rem;
align-items: center;
}
.btn-group .btn-min {
flex-shrink: 0;
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer building compact button groups for a
design system.
Goal: Use width: min-content on buttons so each button shrinks to exactly
fit its label — no fixed widths, no unwanted stretching in flex or grid.
Technical constraints:
- Set width: min-content on the button element.
- Add white-space: nowrap to prevent the label from wrapping, which
would produce a very narrow tall button.
- Add flex-shrink: 0 when the button is inside a flex container so
flex cannot compress it below its min-content width.
- Use oklch() for any color values — no hex or rgba.
- Handle very long label text gracefully: if a label is excessively
long, apply max-width and text-overflow: ellipsis as a safety net.
Framework variant (pick one):
A) Vanilla CSS — .btn-min utility class and .btn-group flex wrapper,
applicable to any button or anchor element.
B) React component — Button component that accepts label, onClick, and
variant props; sizes to min-content by default and accepts a
fullWidth boolean prop to opt into 100% width instead.
Edge cases to handle:
- Very short labels (e.g. "OK") may produce a button narrower than the
44px WCAG touch target — add min-width: 2.75rem as a floor.
- In CSS grid, buttons stretch to fill cells by default — use
align-self: start or justify-self: start as an alternative to
min-content for grid children.
- For RTL layouts, the min-content calculation is the same; no
directional adjustment is needed since the width is content-based.
- When the label is dynamic and may be empty, ensure the button has
a minimum visible width so it does not collapse to zero.
Return CSS only (or a React component if variant B).
What min-content sizing means
The min-content keyword resolves to the smallest width at which the element's content avoids overflow. For a button with a text label, that is the width of the label text plus horizontal padding — assuming no line breaks are allowed. This is why white-space: nowrap must accompany width: min-content on buttons: without it, the browser is free to break the label at any space character, producing a very narrow, very tall button.
With white-space: nowrap in place, min-content equals the full single-line width of the label. Each button in a group sizes independently to its own label, so "Save" is narrower than "View details" — no shared fixed width required. This makes button groups self-organizing: add or rename a button and the layout adjusts automatically.
Use cases for button sizing
The most common use case is an inline action group — Save / Cancel, Accept / Decline, Edit / Delete — where each button should wrap its own label without any of them growing to match the widest sibling. This is distinct from a form submit button that should span the full width of its form; those buttons want width: 100%, not min-content.
Another common case is a button inside a card or list item. When the card is inside a grid, grid children default to align-self: stretch; justify-self: stretch, which would otherwise stretch the button to fill the cell. Setting width: min-content on the button overrides this, keeping it compact regardless of the card's width. Alternatively, align-self: start on the button achieves the same visual result without the min-content keyword.
For toolbars and nav bars where every button should have an equal width, min-content is the wrong tool — use a fixed width or min-width instead to align button edges. Reserve min-content for cases where you explicitly want each button sized independently.
Combining with fit-content
The fit-content keyword is a middle ground between min-content and max-content. It allows an element to grow up to its available space but caps it at the element's intrinsic preferred width. For buttons, fit-content behaves the same as min-content in most cases because buttons do not have long runs of unwrapped text that would make the preferred width exceed the available space.
Where fit-content differs is when the button label is genuinely long. With width: min-content; white-space: nowrap, the button will overflow its container if the label is longer than the container. With width: fit-content; white-space: nowrap, the same overflow can occur. For buttons with potentially long dynamic labels, combine width: min-content with a max-width cap and text-overflow: ellipsis to prevent overflow while still sizing tightly for short labels.
Browser support and fallbacks
The min-content keyword for width is part of the CSS Intrinsic and Extrinsic Sizing specification and is in Baseline Widely Available. It is supported in all modern browsers: Chrome, Firefox, Safari, and Edge. No vendor prefixes are required.
For older browsers that do not recognize width: min-content, the declaration is ignored and the button falls back to its default sizing — typically auto, which sizes to content in inline-block and to the flex or grid cell in flex and grid layouts. This fallback is usually acceptable: the layout degrades gracefully to buttons that may be slightly wider, without any broken UI.