Fluid Type That Sizes Itself: A Practical clamp() System
Replace a stack of font-size media queries with a handful of clamp() tokens that scale smoothly between phone and desktop — no breakpoints, no jank.

On this page
Media-query typography ages badly: you tune three or four breakpoints, then a new device lands between them and the rhythm breaks. clamp() lets the browser interpolate for you, so a heading grows continuously from phone to desktop.
The shape of a fluid token
clamp(MIN, PREFERRED, MAX) picks the middle value until it hits a bound. Pair a rem floor and ceiling with a vw-based preferred value and the type scales with the viewport but never runs away:
:root {
--step-0: clamp(1rem, 0.92rem + 0.4vw, 1.2rem);
--step-1: clamp(1.25rem, 1.1rem + 0.75vw, 1.6rem);
--step-2: clamp(1.56rem, 1.3rem + 1.3vw, 2.25rem);
--step-3: clamp(1.95rem, 1.55rem + 2vw, 3rem);
}
h1 { font-size: var(--step-3); }
h2 { font-size: var(--step-2); }
p { font-size: var(--step-0); }
Anchor the maths to a ratio
Pick a modular scale — 1.2 on mobile, 1.33 on desktop is a comfortable pair — and let each step inherit from it. Because the floor and ceiling are both in rem, the whole system still respects the reader’s browser font-size setting.
Keep it accessible
Never clamp with vw alone. A viewport-only value can shrink text below legibility or defeat zoom. The rem term in the preferred slot keeps zoom working and guarantees a real minimum.
The payoff
One declaration per step, zero media queries, and copy that reflows gracefully on every screen in between. Delete the breakpoints — the browser interpolates better than your @media ladder ever did.
Related reading
Building a Mobile-First Bento Grid That Doesn't Fall Apart
How we compose a responsive Bento layout with CSS Grid that collapses gracefully from a six-column canvas down to a single column — no media-query soup.
