Guide

← CSS Clamp Calculator

Should Your clamp() Values Use rem or px? Where the Unit Actually Matters

Min and max should be rem. The preferred value is where the argument lives. Here is the zoom math, the one place px is fine, and the 2.5x ceiling rule.

The safest fluid-type pattern I know is one line, and the units are doing most of the work:

h1 { font-size: clamp(3rem, 2.296rem + 3vw, 5rem); }

That declaration says: 48px on a 375px phone, 80px from 1440px up, smooth in between. Every number is in rem except the vw term, and that choice is deliberate. The question of rem vs px in CSS clamp() has a clear answer for the min and max, a subtler answer for the preferred value, and one honest exception.

Min and max: use rem, no real debate

The min and max are the floor and ceiling, and they should be rem because rem follows the user's root font-size setting. If someone has bumped their browser default to 20px or 24px, a rem floor rises with it and a px floor does not. That is the entire accessibility argument, and it costs nothing: you are already thinking in pixels when you design, so divide by 16 and write rem.

Mixing a rem min with a px max inside the same clamp is legal CSS, and it is a common source of subtle bugs, because the two bounds now respond to different things. Keep one unit for min, intercept, and max. The vw term is always a viewport percentage; it never gets converted to rem.

One more constraint on the ceiling, from WCAG 1.4.4, which requires text to be resizable to 200%. The working rule, demonstrated by Maxwell Barvian in Smashing Magazine: keep the max at no more than 2.5 times the min. clamp(1.5rem, ..., 3rem) is fine at 2x. clamp(1rem, ..., 4rem) is not, because at 4x the range the ceiling can silently cap zoomed text. My example above is 80 / 48 = 1.67x, comfortably inside. When I generate a scale I check this ratio before anything else, because a declaration that fails it will fail a zoom test no matter how careful the preferred value is.

rem vs px in the preferred value: the part people get wrong

The preferred value is usually written as a slope in vw plus an intercept, and the temptation is to write the whole thing in vw: clamp(3rem, 6.4vw, 5rem). It scales fluidly, it looks clean, and it fails the user who zooms. Viewport units track the CSS viewport, and when a user zooms to 200%, the viewport shrinks exactly when the text needs to grow. The fix is the rem term in the preferred value: 2.296rem + 3vw responds to both the viewport width and the user's zoom or font-size preference, because the rem component scales with them.

Here is the worked math for the declaration at the top, so you can see where each number comes from. Target 48px at a 375px viewport and 80px at 1440px. Convert the bounds to rem: 48 / 16 = 3rem, 80 / 16 = 5rem. Slope: (80 - 48) / (1440 - 375) = 32 / 1065 = 0.03005, which is 3vw. Intercept: 48 - 0.03005 × 375 = 36.7px, which is 2.296rem. Result: clamp(3rem, 2.296rem + 3vw, 5rem). That is the whole recipe, and it is also exactly what the calculator on this site emits.

The one place px is fine

Non-text lengths. Padding, margins, gaps, and border radii do not carry the text-resizing obligation, so a clamp() with px bounds on section padding is not an accessibility failure. The other legitimate px case is matching a device-pixel comp before converting: if the design was specced in px and you will convert to rem later, px is a fine intermediate. Just convert before shipping. And body text is a separate decision entirely: it usually should not use clamp() at all. A fixed 1rem lets user font-size preferences flow through untouched, which is the whole point of the rem argument above.

One unit for min, intercept, and max, always rem for text. The preferred value gets the rem + vw mix, never vw alone. Check the max-to-min ratio stays under 2.5. Test at 200% zoom with the browser default font size bumped up, because that is the test the rule is really about. Everything else, the spacing, the radius, the gaps, gets whatever unit is convenient.

One open thread I am watching: container query units like cqi may eventually move the fluid term from the viewport to the container, which would change where the rem anchoring needs to live. For now, vw plus rem is the settled pattern.

Frequently asked questions

Should I use rem or px in CSS clamp()?

Use rem for the min and max so they respect the user's root font-size setting, and use a rem + vw mix for the preferred value so browser zoom keeps working. px is fine for non-text lengths like padding and gaps.

Can you mix rem and px inside one clamp()?

It is legal CSS, but it is a common bug source because the bounds then respond to different things. Keep one unit for the min, the intercept, and the max.

What is the 2.5x rule for clamp()?

Keep the max at no more than 2.5 times the min. Beyond that ratio, the ceiling can cap text that a zoomed user needs to keep growing, which risks a WCAG 1.4.4 failure.

Does the preferred value need a rem term?

For text, yes. A vw-only preferred value tracks the viewport width and barely responds to zoom. Adding a rem component anchors the size to the user's font setting so zoom works.

Generate accessible clamp() values

Every value this calculator emits uses rem-based bounds, so your fluid type stays zoom-safe.

Open the CSS Clamp Calculator

Prefer this by email? Get future guides in your inbox.