CSS clamp() Calculator
Turn min and max sizes at two viewports into a correct rem-based clamp() expression, with the math shown — entirely on this device.
clamp(1rem, 0.8239rem + 0.7512vw, 1.5rem)- Slope — size change per viewport px
(24 - 16) / (1440 - 375) = 0.0075 - Slope in vw (slope × 100)
0.7512vw - Intercept — size at a 0px viewport
16 - 0.0075 x 375 = 13.1831px - Intercept in rem
0.8239rem - Assembled expression
clamp(1rem, 0.8239rem + 0.7512vw, 1.5rem)
Press ? for shortcuts
Do it offline:$ node -p 's=(24-16)/(1440-375);i=16-s*375;"clamp(1rem, "+(i/16).toFixed(4)+"rem + "+(s*100).toFixed(4)+"vw, 1.5rem)"'
How to use it
- Enter the minimum and maximum sizes, in px or rem — the unit toggle applies to the pair.
- Set the two viewport widths; the page loads with the 375px and 1440px teaching sample.
- Leave root at 16 unless your stylesheet changes it; pick rem or px output.
- Read the expression and the numbered derivation, then copy it or download a .css snippet.
- Drag the preview slider across its 240–2560px track — for the pre-filled sample that reaches past both endpoints.
Enter the size you want at a narrow viewport and the size at a wide one; the calculator solves the line between them and emits a copy-ready CSS clamp() expression — rem-based, every step of the math printed. A slider previews the computed size at any width from 240 to 2560px, and everything runs on this device: no upload, no account.
How it works
The fluid middle is a line through two points. Slope: (24 - 16) / (1440 - 375) — about 0.0075px per viewport pixel, times 100 the 0.7512vw coefficient. Intercept: 16 - 0.0075 x 375 — 13.1831px at a zero-width viewport, or 0.8239rem at a 16px root. Bounded by the two sizes, that reads clamp(1rem, 0.8239rem + 0.7512vw, 1.5rem).
The rem default is the accessibility half. WCAG 2.2's 1.4.4 (Resize Text) asks that text scale to 200%; a reader raising the browser default from 16px to 32px doubles every rem — the sample's 1rem floor becomes 32px, its 1.5rem ceiling 48px. The px flavor, clamp(16px, 13.1831px + 0.7512vw, 24px), holds that reader at 16px forever.
Displayed figures are rounded to four decimals — extreme roots or viewport widths earn extra digits — and the solve itself runs unrounded. Re-evaluating the printed expression at 375px and 1440px lands within 0.01px of the requested 16 and 24; outside those widths the bounds hold the result flat.
Examples
16px at 375px → 24px at 1440pxclamp(1rem, 0.8239rem + 0.7512vw, 1.5rem)The classic fluid-type ramp and this page's pre-filled sample: slope 0.0075 (0.7512vw), intercept 13.1831px — 0.8239rem at the 16px root.
12px at 375px → 32px at 1440pxclamp(0.75rem, 0.3099rem + 1.8779vw, 2rem)A spacing ramp: 12px gaps on phones growing to 32px on desktops. A steeper change over the same run yields a larger coefficient, 1.8779vw.
24px at 375px → 18px at 1440pxclamp(1.125rem, 1.632rem - 0.5634vw, 1.5rem)Allow descending sizes lets a heading shrink as the viewport widens; the sign folds into the expression, and the lower bound, 1.125rem, becomes the size at the widest viewport.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
Equal sizes collapse to a constant
Enter 18 and 18: the result is the bare value 1.125rem plus the note that there is no fluid range — clamp() unnecessary. The preview line stays flat.
Slopes under 0.05vw are flagged
16px to 16.4px solves to 0.0376vw and earns a warning chip calling the result effectively constant — under half a pixel of change per thousand viewport pixels.
Why descending bounds are auto-ordered
CSS resolves clamp() as max(MIN, min(VAL, MAX)); write the bounds backwards and MIN simply wins, so for descending pairs the tool sorts them numerically before printing.
px output trades away a user preference
The px curve matches rem only at default settings; readers who raised their font size get nothing from it. Selecting px adds a warning chip citing WCAG 1.4.4.
Roots other than 16px respell the rem values
At root 20 the sample becomes clamp(0.8rem, 0.6592rem + 0.7512vw, 1.2rem) — identical pixels, different arithmetic. Match the field to your html rule.
vw only — container-query units are out of scope
cqw, cqi and the logical units vi and vb measure different reference boxes, so viewport-width math does not transfer; none are supported here.
Beyond the two viewports the size holds
The outer arguments pin everything past the endpoints: the sample evaluates to 16px at a 320px viewport and 24px at 2560px — flat tails, by design.
Common errors
Min viewport must be smaller than max- The two widths are swapped or equal — no range to interpolate across; the message covers equality too.
Max size is smaller than min — turn on "Allow descending sizes" for a negative-slope clamp().- A guard against transposed fields: shrinking while the viewport grows is legitimate, so the toggle asks for intent first.
Root size must be greater than 0.- rem is a multiple of the root, so a zero or negative root makes conversion meaningless; 16 mirrors the browser default.
Min size must be a number.- An empty or non-numeric field cannot enter the solve; each of the five inputs reports its own field-named version.
Max size exceeds the ±10,000px limit (MAX_SIZE_PX).- Sizes are capped at ±10,000px after unit conversion, viewports at 100,000px — past a cap the tool refuses and names the limit.
FAQ
Is clamp() accessible?
With rem output, largely yes: the bounds and the intercept scale with the reader's font-size preference, so a doubled default doubles the guaranteed minimum. px output ignores that preference — selecting it raises a warning. The floor you set is enforced literally, so keep it readable.
Why does the output default to rem instead of px?
The root font size is the one typography dial readers own, and rem is the unit that listens to it; px matches only for visitors who never touched their settings. px stays available for lengths that should not track font size, behind the WCAG 1.4.4 note.
What happens above the max viewport (or below the min)?
Nothing keeps growing — that is the point of the outer arguments: below 375px the sample renders 16px, past 1440px it renders 24px, no media query needed. The slider deliberately runs past both endpoints to show the flat segments.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Re-run the solve (results already refresh on every valid edit).
- ⌘/Ctrl + C
- Copy the expression when nothing is selected; focused number fields are never intercepted.
- ⌘/Ctrl + Shift + C
- Copy the expression even while a selection exists.
- ⌘/Ctrl + S
- Download the expression as a .css snippet, overriding the browser's save-page dialog.
- t
- Cycle the theme (ignored while a field has focus).
- ? or ⌘/Ctrl + /
- Open this page's keyboard-help dialog.
- Esc
- Close the topmost dialog without touching the inputs.