Fluid Typography
When to Use
When a client wants text that scales smoothly between viewport sizes with no jarring breakpoint jumps — the standard approach for modern responsive typography.
Decision
| Client asks for... | Use... | Why |
|---|---|---|
| Font size scales with viewport | clamp() |
One line, min/max/preferred |
| Spacing scales with viewport | clamp() on gap, padding, margin |
Same technique |
| Type scale system (h1-h6) | clamp() per heading level |
Consistent hierarchy at all sizes |
| Container-relative sizing | cqi units |
Scales with container, not viewport |
Pattern: Fluid Type Scale
:root {
--text-xs: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem);
--text-sm: clamp(0.875rem, 0.8rem + 0.35vw, 1rem);
--text-base: clamp(1rem, 0.9rem + 0.5vw, 1.125rem);
--text-lg: clamp(1.125rem, 0.95rem + 0.75vw, 1.5rem);
--text-xl: clamp(1.5rem, 1rem + 1.5vw, 2.5rem);
--text-2xl: clamp(2rem, 1.2rem + 2.5vw, 3.5rem);
--text-3xl: clamp(2.5rem, 1.5rem + 3vw, 5rem);
}
h1 { font-size: var(--text-3xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }
p { font-size: var(--text-base); }
Pattern: Fluid Spacing
:root {
--space-xs: clamp(0.25rem, 0.2rem + 0.25vw, 0.5rem);
--space-sm: clamp(0.5rem, 0.4rem + 0.5vw, 1rem);
--space-md: clamp(1rem, 0.8rem + 1vw, 2rem);
--space-lg: clamp(1.5rem, 1rem + 2vw, 4rem);
--space-xl: clamp(2rem, 1.5rem + 3vw, 6rem);
}
.section { padding-block: var(--space-xl); }
.card { padding: var(--space-md); gap: var(--space-sm); }
Pattern: Container-Relative Typography
.card-container {
container-type: inline-size;
}
.card__title {
font-size: clamp(1rem, 3cqi, 2rem);
}
.card__body {
font-size: clamp(0.875rem, 2cqi, 1.125rem);
}
The clamp() Formula
clamp(MIN, PREFERRED, MAX)
0.9rem + 1vw)
- MAX: largest the text will ever be (design ceiling)
Quick formula: clamp(minRem, calcRem + Xvw, maxRem) where X = (max - min) / (maxViewport - minViewport) * 100.
Tools: Utopia.fyi generates fluid type/space scales with custom min/max viewports.
Browser support: clamp(): all browsers (Baseline 2020). cqi: all browsers (Baseline 2023). Fully production-ready.
Common Mistakes
- Body text below 1rem — accessibility minimum; ensure
clamp()min is ≥ 1rem for body text - Too aggressive vw component — text that changes too drastically feels unstable; keep vw multiplier ≤ 3vw for most uses
- Not combining with
text-wrap: balance— fluid headings benefit from balanced line breaks - Using only vw units (no clamp) — pure
font-size: 3vwhas no min/max, becomes illegible on small/huge screens
See Also
- Modern CSS: Container Units → cqi/cqw for component-level sizing
- Modern CSS: text-wrap → balanced headings
- Motion Design Tokens → consistent spacing system
- Reference: Utopia.fyi — fluid type/space calculator