Skip to content
Craft & CSS

Fluid type without magic numbers

clamp() is everywhere and understood nowhere. The math that makes fluid type explainable — minimum, maximum, and a slope you can defend in a code review instead of a number you found in a tweet.

Answers How do I size type so it works on a phone without magic numbers?a clamp() with a stated reason beats a pile of breakpoints, and the numbers hold at both ends.

Intermediate2 min read (computed · recorded 9)updated 2026-09-10typographyclampfluid typecss

What clamp actually computes

clamp(min, preferred, max) picks the middle value when it fits between the bounds. The middle is usually a vw-based expression, and that expression is a straight line: at some viewport width it equals the minimum, at another it equals the maximum, and between them type scales linearly. Magic numbers are just slopes chosen by trial; the fix is choosing the slope on purpose.

The defensible recipe: pick your type size at a small viewport (the minimum), pick it at a large viewport (the maximum), and decide at which widths the size stops changing. The vw slope is then arithmetic: (max - min) / (max-width - min-width).

fluid-type.ts
Goal: 16px @ 360px viewport -> 20px @ 1280px viewport.
Slope = (20 - 16) / (1280 - 360) = 4 / 920 = 0.00435

clamp(16px, 0.435vw + ?px, 20px)

Solve the intercept at 360px:
0.00435 * 360 = 1.57 -> need 16 - 1.57 = 14.43px base

clamp(16px, calc(0.435vw + 14.43px), 20px)
-- a line you can explain in one sentence.

The rules that keep it sane

  • Anchor every clamp to real breakpoints you already use — the min viewport (small phone), the max viewport (large desktop). If your container maxes at 1200px, scaling type to 2000px viewports is scaling for empty space.
  • Never clamp a single size in isolation — scale the whole type ramp together so the hierarchy's *ratios* stay constant, or headings will outgrow their paragraphs at some width.
  • Use rem for the bounds so user font-size settings still scale your type; a clamp in px ignores the browser's minimum font size and accessibility settings.
  • Container queries change the game: with container query units you can scale type to the *component* width, which matters for sidebars and cards that never reach viewport scale.

When fluid type is the wrong tool

Long-form reading: body text that grows with the viewport fights the reader's preferred measure. For articles, fix the measure (60–75ch) and let font size stay steady across a wide range — fluid type belongs to display and headings, not paragraphs. If a line of body copy changes size between two monitors side by side, a reader who notices will not thank you.

Practise the lesson

Theory sticks when you ship it. These original Motif assets put this guide's lesson to work — open one and copy it into your own page.