How CSS clamp() works (formula and examples)
clamp(MIN, PREFERRED, MAX) returns the preferred value, but never less than MIN and never more than MAX. The preferred value is usually a formula involving viewport units (vw), which makes the result scale with the browser window. A single line replaces a stack of media queries:
font-size: clamp(1rem, 0.5rem + 2vw, 2rem);
This font-size is at least 1rem (16px), grows as the viewport widens, and never exceeds 2rem (32px). The middle expression 0.5rem + 2vw is the formula that produces the actual size at any viewport width.
The arguments explained
clamp(MIN, PREFERRED, MAX);
- MIN: lower bound. Result never falls below this.
- PREFERRED: target value. Usually combines a fixed value with
vwto scale. - MAX: upper bound. Result never exceeds this.
The browser evaluates PREFERRED at the current viewport, then clips to [MIN, MAX]. If PREFERRED evaluates to something less than MIN, the result is MIN. If greater than MAX, the result is MAX. Otherwise, the result is PREFERRED.
How the preferred value scales
The viewport unit 1vw equals 1% of the browser’s width. At a 1000px viewport, 1vw = 10px. So 2vw = 20px, 5vw = 50px, etc.
For 0.5rem + 2vw (treating 1rem as 16px):
| Viewport | 2vw | 0.5rem + 2vw | Clamped (1-2rem) |
|---|---|---|---|
| 320px | 6.4px | 14.4px | 16px (MIN) |
| 480px | 9.6px | 17.6px | 17.6px |
| 768px | 15.4px | 23.4px | 23.4px |
| 1024px | 20.5px | 28.5px | 28.5px |
| 1280px | 25.6px | 33.6px | 32px (MAX) |
| 1920px | 38.4px | 46.4px | 32px (MAX) |
Below 320px the size is pinned at the 1rem MIN. Above ~1240px it is pinned at the 2rem MAX. Between those points, the font scales linearly.
Deriving clamp() from two breakpoints
The most useful clamp() pattern: start at size A on viewport W₁, end at size B on viewport W₂. Find the formula that connects them.
The preferred value should be a linear function of viewport width: intercept + slope × vw.
For 16px at 320px scaling to 32px at 1280px:
- Slope per vw: (32 - 16) / (1280 - 320) × 100 = 16 / 960 × 100 = 1.667
- Intercept: 16 - 1.667 × 3.2 = 10.67px
Final formula:
font-size: clamp(1rem, 10.67px + 1.67vw, 2rem);
Verify at the endpoints:
- 320px: 10.67 + (320 × 1.67/100) = 10.67 + 5.34 = 16.01px ✓
- 1280px: 10.67 + (1280 × 1.67/100) = 10.67 + 21.38 = 32.05px ✓
The CSS clamp calculator generates this directly from your two breakpoint values.
Common clamp() patterns
Fluid heading
h1 {
font-size: clamp(1.75rem, 1.25rem + 2.5vw, 3rem);
}
Scales h1 from 28px at 480px viewport to 48px at 1280px.
Fluid section padding
section {
padding-block: clamp(2rem, 4vw, 5rem);
}
Vertical padding grows from 2rem on small screens to 5rem on large.
Fluid container width
.container {
width: clamp(20rem, 90%, 80rem);
}
Container is at least 320px wide, prefers 90% of parent, but never exceeds 1280px.
Fluid grid gap
.grid {
gap: clamp(1rem, 2vw, 2rem);
}
Gap scales from 16px to 32px linearly with viewport width.
Fluid ratio with rem fallback for accessibility
font-size: clamp(1rem, 0.5rem + 2vw, 2rem);
This pattern combines a rem-based intercept (which respects user font-size preferences) with a vw-based scaling factor. Pure vw formulas can break user zoom in some browsers; mixing rem with vw avoids the problem.
When NOT to use clamp()
clamp() is built for continuous scaling. It works less well when you need:
- Different layouts at breakpoints (use media queries for layout structure)
- Discrete typography steps (use CSS variables and media queries for explicit sizes)
- Conditional rules (
@containerqueries handle these better) - Non-monotonic behavior (clamp can only interpolate linearly between two endpoints)
For typography that should jump in discrete steps rather than scale smoothly, fall back to media queries:
.title { font-size: 1.5rem; }
@media (min-width: 768px) { .title { font-size: 2rem; } }
@media (min-width: 1280px) { .title { font-size: 3rem; } }
Browser support
clamp() is supported in all modern browsers (Chrome 79+, Firefox 75+, Safari 13.1+, Edge 79+). For practical purposes, it has been universally available since 2020.
The related functions min() and max() work the same way:
width: min(100%, 80rem); /* whichever is smaller */
height: max(50vh, 30rem); /* whichever is larger */
clamp(MIN, P, MAX) is mathematically equivalent to max(MIN, min(MAX, P)).
Quick formula reference
For a target size S at viewport V (both in px):
preferred = (S - intercept) / (V / 100) vw + intercept px
Or use the slope/intercept method shown above for any two breakpoints. The CSS clamp calculator generates the full clamp() function from minimum size, maximum size, minimum viewport, and maximum viewport in one step.
CalculateY