What does CSS clamp() do?
clamp(MIN, PREFERRED, MAX) returns the preferred value as long as it stays between the minimum and maximum, and otherwise returns the nearest bound. When the preferred value mixes a fixed length with a viewport unit — for example 0.8333rem + 0.8333vw — the result grows in a straight line as the browser gets wider, then stops at the bounds. That is fluid typography in one declaration, with no media queries.
The hard part is the math. To go from 16px at a 320px viewport to 24px at 1280px, you need the line through those two points: the slope is (24 − 16) ÷ (1280 − 320) = 0.008333, which becomes 0.8333vw once multiplied by 100, and the intercept is 16 − 0.008333 × 320 = 13.333px, or 0.8333rem. This generator does that calculation for any sizes, units and viewports, and shows the result at every common breakpoint.
The same technique works for any length: padding, gaps between grid items, section spacing, border radius or max-width. Using one fluid scale for both type and space keeps a layout proportional from phones to wide desktops.
How to use the CSS Clamp Generator
- Enter the smallest and largest size in pixels or rem, and the viewport widths where the scaling should start and stop.
- Check the root font size (16px unless you change it) and choose how many decimals to output.
- Pick the CSS property — or a custom property such as
--step-1for a type scale. - Drag the viewport slider to preview the size, review the breakpoint table, then copy the declaration or just the
clamp()value.
Example
A fluid heading, section padding and type-scale token generated with the default 320px → 1280px range:
h1 {
/* 32px at 320px → 56px at 1280px */
font-size: clamp(2rem, 1.5rem + 2.5vw, 3.5rem);
}
.section {
/* 24px → 64px */
padding-block: clamp(1.5rem, 0.6667rem + 4.1667vw, 4rem);
}
:root {
--step-1: clamp(1.125rem, 1.0417rem + 0.4167vw, 1.375rem);
}The formula
slope = (maxSize − minSize) ÷ (maxViewport − minViewport)intercept = minSize − slope × minViewport(converted to rem by dividing by the root font size)preferred = intercept rem + slope × 100 vw- Result:
clamp(minSize, intercept + slope·100vw, maxSize)
Accessibility: keep a rem component
WCAG success criterion 1.4.4 Resize Text requires that text can be enlarged to 200% without loss of content. Browser zoom shrinks the viewport in CSS pixels, so a size made only of vw gets *smaller* in relative terms as people zoom — font-size: 4vw can block zooming almost entirely. Users who change their default font size are ignored completely by vw.
Writing the bounds and the intercept in rem fixes both: the rem part follows the user’s font setting and zoom, and the vw part adds the fluid growth. As a rule of thumb, keep the maximum size at or below 2.5× the minimum; beyond that, the generator warns because the vw share can become large enough to stop text from reaching 200% at some viewport widths. Convert design tokens with the PX to REM Converter first if your scale is in pixels.
Frequently Asked Questions
Is clamp() supported in all browsers?
Yes. clamp(), min() and max() are supported in every current browser and have been since 2020. Only Internet Explorer lacks support; if you must support it, put a fixed fallback declaration before the clamp() one.
Why does my clamp() value not change when I resize the window?
Either the window is outside your viewport range (so a bound is being used), or the preferred value has no viewport unit. Check the breakpoint table: rows marked "Min" or "Max" are clamped. Also make sure no media query overrides the property.
Should the bounds be in px or rem?
Use rem for anything that relates to text, so the user’s preferred font size is honoured. Pixel output is available for cases like borders or fixed-size media, and you can enter values in px while still outputting rem.
Can I use container query units instead of vw?
Yes — replace vw with cqi and set container-type: inline-size on the parent. The math is identical, but the minimum and maximum "viewport" values then describe the container’s width.
Why are the min and max swapped in my output?
If the starting size is larger than the ending size, the value shrinks as the screen grows. CSS clamp() needs its smaller bound first, otherwise the first argument always wins, so the generator orders them correctly and shows a warning.