There's a kind of confidence you get from a CSS function that takes three arguments. clamp(min, preferred, max) looks like a tiny mathematical guarantee — give me your floor, your ceiling, and your slope, and I will deliver the right number at every viewport between phone and TV. For a week it felt like I had typography solved..
I was wrong, but the wrongness was the interesting part.
Why I reached for clamp() in the first place
The blog you're reading lives between two extremes: someone reading it on a 360 px Android in the line at a coffee shop, and someone with a 1920 px monitor at arm's length. In both cases the information density should be roughly the same — about 60–80 characters per line, a comfortable reading rhythm.
Old-school responsive typography solves this with breakpoints. You write @media (max-width: 640px) and override the font size. Three breakpoints and you've covered phone, tablet, desktop. It works, but the transitions are abrupt, and when the user resizes the window they see a jump.
clamp() is supposed to fix that. You pick a minimum, you pick a maximum, you pick a slope, and the value glides between them as the viewport changes.
css .article-title { font-size: clamp(1.85rem, 1.5rem + 1.5vw, 3.2rem); }
The minimum is
1.85rem. The maximum is3.2rem. The middle bit —1.5rem + 1.5vw— is a linear function of viewport width that the browser uses between the floor and the ceiling.
The math is correct. The result, on my MacBook, was a 46 px title that felt like a slide deck.
The trap
The mistake wasn't using clamp(). The mistake was anchoring my maximum to the largest screen I could imagine — a TV — instead of the most common screen — a 1440 px laptop.
When you set the upper bound to "what looks right on a 65-inch display," every screen smaller than a TV gets a value pulled toward TV-large. By the time the formula reaches a normal 1440 px desktop, it's already 90% of the way to oversized. The fluid scale isn't bad; the anchor points were bad.
The fix was embarrassingly small:
- Title max:
3.2rem→2.5rem - Body max:
1.2rem→1.1rem - Body line-height:
1.8→1.7
Nothing else changed. The slope didn't change. The minimum didn't change. Only the ceiling moved.
What I'd do differently
Three things, looking back:
- Anchor to the dominant viewport, not the extreme. "What does this look like on a 1440 px MacBook?" is the right question to start with. TV is an edge case.
- Open a side-by-side comparison early. I should have put the page next to a blog I admire — like Arpit Bhayani's — at the same viewport and looked at them side by side. The numerical similarity hides the visual difference.
- Trust the editorial defaults. Newspapers and book publishers settled this debate a century ago. A 17 px body and a 36 px title at desktop is well-tested; an 18 px body and a 46 px title is "designer trying too hard."
Recap
If you take only one thing from this, take this: clamp() is a tool for making transitions smooth, not for making maximums ambitious. The maximum is where most of your readers will live. Set it for them.
The CSS now looks like this, and reads at 36 px on my MacBook:
css .article-title { font-size: clamp(1.85rem, 1.7rem + 0.67vw, 2.5rem); }
A smaller number, a calmer page.