Home / Snippets / Color & Theming /
fit-content for headings
Use width: fit-content on headings and callout boxes so they size to their text — great for decorative underlines and background highlights that hug the content.
Heading with decorative underline
Gradient underline fits text
Callout box hugs content
Badge / label sizes to content
Quick implementation
/* Heading with decorative underline that fits text */
.fit-heading {
width: fit-content;
padding-bottom: 0.25rem;
border-bottom: 3px solid var(--accent);
}
/* Callout that hugs its content */
.fit-callout {
width: fit-content;
padding: 0.5rem 1rem;
background: oklch(0.24 0.06 265);
border-radius: var(--radius);
font-size: 0.875rem;
}
/* In a flex column, prevents stretching */
.flex-col {
display: flex;
flex-direction: column;
align-items: flex-start; /* or use fit-content on each child */
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer specializing in CSS layout and typography.
Goal: Use width: fit-content on headings and callout elements so that
decorative underlines, background highlights, and badge shapes hug the
text rather than stretching across the full container width.
Technical constraints:
- Apply width: fit-content directly to the heading or callout element.
- For decorative underlines: combine with padding-bottom and border-bottom
so the underline only spans the text width.
- For background highlights: combine with padding and background so the
highlight is content-sized.
- In block flow, fit-content keeps display: block behavior — the next
element still starts on a new line. Only the box width changes.
- In a flex column container, use align-items: flex-start on the parent
as an equivalent alternative so all children shrink to content width.
- Use oklch() for all color values — no hex or rgba.
- Use CSS custom properties (--accent, --radius) where appropriate.
Framework variant (pick one):
A) Vanilla CSS utility classes .fit-heading, .fit-callout, .fit-badge —
each sets width: fit-content plus its own decorative treatment.
B) React component — a <FitBox> component that accepts a variant prop
("heading" | "callout" | "badge") and renders the appropriate class.
Edge cases to handle:
- Long headings: fit-content respects the container boundary — if the text
is longer than the container, the element fills the container and text
wraps normally. No overflow occurs.
- Centered headings: width: fit-content + margin-inline: auto centers the
element while keeping the decoration content-sized.
- Nested flex/grid children: if the heading is a flex child, it may
already be content-sized — test whether fit-content adds any effect or
whether align-self: flex-start on the child is more appropriate.
- RTL layouts: fit-content is writing-mode aware and works correctly in
right-to-left and vertical writing modes.
Return CSS only (or a React component if variant B is chosen).
Why block elements stretch and fit-content fixes it
Block elements — headings, div, p — default to width: auto, which in block flow means "stretch to fill the available inline space." This is sensible for text: you want paragraphs to use the full column width for readability. But it becomes a problem when you attach a visual decoration to the element. A border-bottom underline on a full-width heading stretches all the way across the container, even when the heading text is only a few words wide. A background-color highlight on a callout box fills the entire row rather than hugging the content.
width: fit-content changes the sizing behavior: the element is as wide as its text content (its max-content size), unless that would overflow the container, in which case it wraps and grows to fill the container. The key distinction from display: inline-block is that the element keeps its block formatting context — the next sibling still starts on a new line, margins collapse normally, and the element participates in block layout. Only its width changes to match the content.
The sizing formula and when to use alternatives
Formally, fit-content resolves to min(max-content, max(min-content, available-space)). For a heading in normal block flow this simplifies to: use the text's natural width, unless it's wider than the container (then use the container width). You can think of it as "inline-block sizing, block-flow behavior."
In flex or grid containers, children already shrink to content size when flex-grow and flex-shrink are not set aggressively. In a flex column (flex-direction: column), align-items: flex-start on the parent does the same job as width: fit-content on every child, with a single declaration. Use width: fit-content when you are in block flow context or when you need to target a specific child without affecting siblings.
For centering a content-width heading: combine width: fit-content with margin-inline: auto. The element sizes to content, then the auto margins distribute the remaining space equally, centering the element horizontally.
Accessibility and browser support
width: fit-content is a pure layout property with no accessibility implications. Screen readers and assistive technology are unaffected — the content, heading level, and DOM order remain unchanged. There is no need for additional ARIA attributes when using this pattern.
Browser support for width: fit-content is universal in modern browsers. Older versions required vendor-prefixed alternatives: width: -webkit-fit-content (Safari pre-2020) and width: -moz-fit-content (Firefox pre-2019). If you need to support those versions, add the prefixed declarations first and the unprefixed one last. For most production sites targeting browsers from 2020 onwards, the unprefixed form alone is sufficient.