Sizing Things With CSS clamp()
CSS clamp() is useful when a value should grow with the viewport but should not become absurdly small or large. Fluid type is the obvious example:
h1 {
font-size: clamp(1rem, 4vw, 1.5rem);
}
That one declaration gives the browser three instructions:
- never make the heading smaller than
1rem; - prefer
4vwwhen it fits within the range; - never make it larger than
1.5rem.
In other words, the value grows smoothly until it reaches the maximum. It also stops shrinking when it reaches the minimum. That is often all I need instead of several media queries.
The middle value does the work
The preferred value does not have to be a single viewport unit. A calculation usually gives you more control:
h1 {
font-size: clamp(1.25rem, 1rem + 2vw, 2.5rem);
}
Here, the fixed 1rem provides a base and 2vw adds a fluid part. The minimum and maximum still keep the result within a readable range.
The same approach works for spacing and layout values:
.section {
padding-inline: clamp(1rem, 5vw, 4rem);
}
This lets the side padding breathe on larger screens without wasting most of a narrow screen.
You probably do not need JavaScript
Custom properties work well with clamp() when the values are reused:
:root {
--space-page: clamp(1rem, 5vw, 4rem);
}
.section {
padding-inline: var(--space-page);
}
JavaScript can change those properties, but I would not add it merely to make a value responsive. CSS already knows the viewport size and can recalculate the value itself.
Modern browsers support clamp() well. If an older browser matters for a particular project, place a plain declaration before it as a fallback:
h1 {
font-size: 1.5rem;
font-size: clamp(1.25rem, 1rem + 2vw, 2.5rem);
}
For most sites, clamp() is a small improvement with a good payoff: fewer breakpoints, less repetition, and values that respond between the breakpoints rather than jumping at them.