Guide

← CSS Clamp Calculator

CSS clamp(), Finally Explained: Min, Preferred, and Max

Three values, one function, and a surprising amount of confusion about the middle one. Here is exactly how the browser resolves clamp(), with the math shown at three viewport widths.

The first time I saw clamp(1.25rem, 1.036rem + 1.07vw, 2rem) in a codebase, I nodded confidently and understood approximately one third of it. The min and max were obvious. The middle value, the "preferred" value, looked like someone had sneezed on the stylesheet. It took me an embarrassing number of resized browser windows to internalize what it does. This article is the explanation I wish I had been given.

The three values, in order

clamp(MIN, PREFERRED, MAX) takes exactly three arguments, always in this order:

The mental model that finally clicked for me: the browser computes the preferred value, then clamps it into the [MIN, MAX] range. If preferred is too small, you get MIN. If it is too big, you get MAX. Otherwise you get the preferred value itself, which is what makes the size fluid.

A worked example at three viewport widths

Take a fluid heading size:

h1 { font-size: clamp(1.25rem, 1.036rem + 1.07vw, 2rem); }

This says: never smaller than 1.25rem (20px), never larger than 2rem (32px), and fluid in between. Let us resolve it by hand at three widths. Remember 1vw is 1% of the viewport width, and 1rem is 16px by default.

At 320px (a small phone): 1.07vw = 3.42px = 0.214rem. Preferred = 1.036 + 0.214 = 1.25rem. That equals the MIN exactly, so the browser uses 1.25rem (20px). The floor caught it.

At 768px (a tablet): 1.07vw = 8.22px = 0.514rem. Preferred = 1.036 + 0.514 = 1.55rem. That sits between 1.25 and 2, so the browser uses the preferred value: 1.55rem (about 24.8px). This is the fluid zone doing its job.

At 1440px (a desktop): 1.07vw = 15.41px = 0.963rem. Preferred = 1.036 + 0.963 = 2.0rem. That hits the MAX, so the browser uses 2rem (32px), and it stays there on even wider screens. The ceiling caught it.

Notice the design: this particular expression was derived so the fluid zone spans exactly 320px to 1440px. Below 320 it is pinned at the minimum, above 1440 pinned at the maximum, and everywhere in between it glides. One line replaced what used to be three or four media queries.

Where the preferred value comes from

Nobody hand-writes 1.036rem + 1.07vw from intuition. It comes from a formula (popularized by the Utopia fluid type system): given a MIN size at a minimum viewport and a MAX size at a maximum viewport, the slope is (MAX - MIN) / (MAX_VW - MIN_VW) and the preferred value is yIntercept + slope * 100vw. For 1.25rem at 320px scaling to 2rem at 1440px, the slope is 0.75rem / 70rem of viewport = 0.0107, giving 1.07vw, and the intercept works out to 1.036rem. That is precisely what a clamp calculator computes for you, which is why the tool exists.

The rem rule (the accessibility part)

Here is the detail that separates good clamp() usage from sloppy usage: express MIN and MAX in rem, and include a rem component in the preferred value. There is a tempting shortcut, clamp(20px, 5vw, 32px) or worse, a bare font-size: 4vw, and it has a real cost. Users who increase their browser default font size (many low-vision users do) expect text to scale. Pixel-based bounds ignore that setting; rem-based bounds respect it. MDN documentation explicitly warns that viewport-only sizing can harm accessibility, recommending that you preserve the user's font preferences.

The 1.036rem + floor in our example is doing quiet, important work: even if the viewport contribution shrinks toward zero, the value still anchors to the user's root font size. My rule of thumb: body text stays a plain 1rem so user preferences flow through untouched, and fluid clamp() is reserved for headings and display type where the scaling is a design choice, not a readability risk.

Common mistakes

Browser support is a non-issue at this point: clamp() has shipped in every modern browser since 2020 (Chrome 79, Firefox 75, Safari 13.1). The only holdouts are truly ancient browsers your analytics have hopefully stopped seeing.

Frequently asked questions

What does each value in CSS clamp() do?

clamp(MIN, PREFERRED, MAX) sets a floor, an ideal fluid value, and a ceiling. The browser computes the preferred value (usually involving vw units) and uses it when it falls between MIN and MAX; otherwise it uses whichever bound was crossed.

How do you calculate the preferred value in clamp()?

Use the slope formula: slope = (MAX - MIN) / (MAX_VW - MIN_VW), then preferred = yIntercept + slope x 100vw, where yIntercept = MIN - slope x MIN_VW. For 1.25rem at 320px to 2rem at 1440px this gives clamp(1.25rem, 1.036rem + 1.07vw, 2rem). A clamp calculator does this arithmetic for you.

Is CSS clamp() accessible?

It can be, with one rule: use rem units for the min and max and include a rem component in the preferred value, so the sizes respect the user browser font-size setting. Pixel-only or vw-only expressions can produce text that ignores user preferences. Keep body text at a plain 1rem and reserve clamp() for headings and display type.

Generate your own clamp() values

Dial in min and max sizes, preview the fluid scale live, and copy production-ready CSS.

Open the CSS Clamp Calculator

Keep reading

Fluid Typography vs Media Queries: When to Use clamp()

When one line of clamp() replaces four breakpoints, and when media queries still win.