Home / Snippets / Color /

max-content sizing for tags

Use width: max-content on tag chips to let them grow to their natural content width — perfect for a tag cloud where each chip wraps its label without truncation.

Tag cloud — each chip sizes to its label
CSS Layout max-content Typography Animation oklch() Dark mode Flexbox Grid
Widely Supported
layoutno-js

Quick implementation

/* Tag cloud wrapper */
.tag-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* Individual tag chip */
.tag {
  width: max-content;
  white-space: nowrap;
  padding: 0.25rem 0.75rem;
  border-radius: 999px;
  background: oklch(0.28 0.06 265);
  color: oklch(0.93 0.01 260);
  font-size: 0.8125rem;
  font-weight: 600;
  border: 1px solid oklch(0.36 0.08 265);
}

/* Accent variant */
.tag--accent {
  background: oklch(0.52 0.22 265 / 0.2);
  border-color: oklch(0.52 0.22 265 / 0.5);
  color: oklch(0.72 0.19 265);
}

Prompt this to your LLM

Includes role, constraints, two framework variants, and edge cases to handle.

You are a senior frontend engineer building a tag cloud component for a
content site.

Goal: Use width: max-content on tag chips so each chip grows to its
natural label width — no fixed widths, no truncation, wrapping naturally
in a flex row when space runs out.

Technical constraints:
- Set width: max-content on the tag element.
- Add white-space: nowrap to prevent the label from line-breaking inside
  the chip.
- Wrap tags in a flex container with flex-wrap: wrap and gap so they
  reflow cleanly to new lines when the container is narrow.
- Use border-radius: 999px for a pill shape.
- Use oklch() for all color values — no hex or rgba.
- Handle RTL layouts: use padding-inline instead of padding-left and
  padding-right so the chip mirrors correctly in RTL documents.

Framework variant (pick one):
A) Vanilla CSS — .tag-cloud wrapper and .tag chip classes, with a
   .tag--accent modifier for highlighted tags.
B) React component — TagCloud wraps an array of label strings and
   renders Tag chips; Tag accepts label, accent (boolean), and
   optional href props.

Edge cases to handle:
- Very long tag labels (e.g. a compound phrase) will produce a chip
  wider than its container — add max-width: 100% and overflow: hidden
  with text-overflow: ellipsis as a safety valve.
- For interactive tags (links or toggles), ensure the chip has a
  visible focus ring using :focus-visible and meets the 44px minimum
  touch target height via min-height.
- In RTL documents, use padding-inline: 0.75rem instead of
  padding-left and padding-right to correctly mirror the chip.
- When rendering server-side, avoid relying on JavaScript to measure
  label widths — max-content is a CSS-only solution.

Return CSS only (or a React component if variant B).

What max-content sizing means

The max-content keyword resolves to the element's preferred width — the width the content would occupy if there were no container constraints. For a tag chip with a text label, that is the full single-line width of the label text plus horizontal padding. The element never shrinks below this width, and it never grows beyond it. Each chip is exactly as wide as its label requires, no more, no less.

Compare this to min-content, which gives the smallest width that avoids overflow. For short single-word labels without spaces, both keywords resolve to the same value. For multi-word labels, min-content breaks at every space, producing a very narrow chip; max-content keeps the full label on one line. Adding white-space: nowrap makes both keywords equivalent for tag text, but max-content is the more semantically accurate choice when the intent is "size to the full label".

Tag cloud pattern

The tag cloud pattern pairs width: max-content chips with a display: flex; flex-wrap: wrap; gap: 0.5rem wrapper. The wrapper distributes chips horizontally and wraps to a new row when the current row is full — exactly like inline elements, but with precise gap control instead of the margin hacks that inline elements require.

Each chip sizes independently to its own label. "CSS" is narrow; "max-content" is wider; "Typography" is wider still. No chip stretches to match its neighbors, and no chip is truncated. This makes the pattern robust against dynamic content — adding, removing, or renaming a tag requires no CSS change, and the layout adapts automatically.

For interactive tag clouds where users can select or filter by tag, toggle a state class that changes background and border-color. The chip width remains content-driven regardless of selection state, so toggling does not cause layout reflow.

Comparing min-content, max-content, and fit-content

The three intrinsic sizing keywords differ in how they relate content width to available space. min-content gives the smallest width that avoids overflow — for text, it wraps at every soft-wrap opportunity. max-content gives the preferred width as if space were unlimited — no line breaks beyond what the content itself forces. fit-content is clamped: it behaves like max-content but caps at the available space, equivalent to min(max-content, available).

For tag chips with white-space: nowrap, all three keywords resolve to the same value — the full single-line label width. The practical distinction emerges in edge cases: if a chip label is longer than the container, max-content overflows the container, fit-content caps at the container edge (potentially truncating without additional overflow handling), and min-content also overflows since wrapping is prevented. A max-width cap handles all three cases safely.

Browser support

The max-content keyword for width is in Baseline Widely Available and is supported in all modern browsers: Chrome, Firefox, Safari, and Edge. No vendor prefixes are required. The keyword has been widely supported since 2018, making it safe for production use without fallbacks for any realistic browser target.

Older browsers that do not recognise width: max-content fall back to their default sizing. In a flex container, flex items without an explicit width use flex-basis: auto, which resolves to the item's intrinsic size — effectively the same as max-content for most text content. The graceful degradation is therefore very close to the intended behavior, with chips sizing naturally to their labels in older browsers as well.