Fluid type scales
clamp() with a viewport-relative middle value
Chrome79
Edge79
Firefox75
Safari13.1
Features it needs
- min(), max(), and clamp()Widely available
clamp() takes a minimum, a preferred value and a maximum, so a heading can scale with the viewport and still stop before it becomes unreadable at either end. Mixing rem into the preferred value, rather than using vw alone, keeps the text responsive to the user's font size, so zooming still works. Container query units swap the viewport for the component's own width when a card needs to scale independently of the page.
When this applies
A heading or display type should scale between a minimum and maximum size with the viewport.
The native approach
h1 {
/* min 2rem, max 4rem, scaling with the viewport between. */
font-size: clamp(2rem, 1.5rem + 2.5vw, 4rem);
}
/* Scale with the container instead of the viewport. */
.card h2 {
font-size: clamp(1.25rem, 0.9rem + 2cqi, 2rem);
}When the dependency is still right
An answer that always says "the platform covers it" is worse than no answer. These are the cases where this one does not hold.
- You need text to fit an exact box on one line, which is what fitty and textfit actually do. clamp() scales against the viewport or container, and knows nothing about the string's rendered width.
- The text is user-generated and of unpredictable length, so no fixed scale will fit every case.
- You need to fit text to a shape or along a path.
Building it
This catalog stops at the swap. These guides go through the implementation and the fallbacks. They come from Google Chrome's modern-web-guidance, Apache-2.0.