CSS Clamp Calculator · Guides

The Corners That Don't Know How Big They Are

How to use clamp() for fluid border radius in CSS.

Published October 23, 2026

How do you make border-radius fluid in CSS? Watch a 16px card radius across screen sizes. On a phone it eats the corners alive; on a 27-inch monitor it looks like you forgot to round them at all. One fixed value cannot serve both. Developers fluidify type, spacing, and padding, then leave the radius frozen. The eye notices the mismatch before it can name it.

The reason percentages are not the fix: a percentage radius measures against each dimension separately. border-radius: 10% on a wide, short card rounds the top edge proportionally more than the side edge, and the corners come out elliptical. That looks broken next to a sibling element that is more square. Pixel radii stay circular; they just do not scale. So the job is to scale a pixel radius with the layout without shipping a breakpoint per corner.

Fluid type gets a whole vocabulary for this; border radius gets none. But it is the same math. The radius should track a viewport-relative size between two sensible endpoints. The minimum comes from your smallest token. The maximum comes from your largest. And the middle, the part that makes it fluid, is a viewport width factor tuned so the crossover happens where your layout actually changes. If you use a design token scale like --radius-md: 8px through --radius-2xl: 24px, those two numbers are your guardrails, and 2vw is your candidate middle.

The values, worked out

Here is the line, before anything else:

.hero-card {
  border-radius: clamp(8px, 2vw, 24px);
}

Walk it through the widths. At a 400px phone, 2vw is 8px, so the minimum holds: tight corners that fit a small card. At 768px, 2vw is about 15px, comfortably between the tokens. At 1200px it would be 24px anyway, and the maximum caps it there, so ultrawide monitors don't get dinner plates. The corner scales roughly with the container while never escaping the design system's own bounds. That is the whole trick, and it costs one declaration.

Three things worth getting right. First, keep the min and max from the token scale rather than inventing them. A fluid value that can reach 24px while your largest token is 16px breaks the system the scale was built to enforce. Second, match the vw factor to the element's own rhythm. A button that scales its padding with clamp(8px, 2vw, 16px) pairs naturally with a radius at half the vw factor; details live in our button padding guide. Third, watch the crossover: if your max is reached before your layout's main breakpoint, the radius goes flat while everything else keeps growing. The math for that crossover is the same as the never-reaches-max problem, and it is worth five minutes with the calculator rather than eyeballing it.

One more pattern, because it shows up in component libraries constantly: pair the radius with fluid padding on the same element. A card whose padding and radius both scale at 2vw reads as one system at every width. Fixed radius plus fluid padding is the specific mismatch that makes resizes feel cheap. Store the whole expression in a custom property and the pairing becomes the default.

No media queries, no percentage ellipses, and no fallbacks in any browser your users actually run.

Frequently asked questions

How do you make border-radius fluid with clamp()?

border-radius: clamp(8px, 2vw, 24px): a minimum pixel value, a preferred viewport-relative value, and a maximum pixel value. The radius scales with the viewport and never escapes the bounds.

Why not use a percentage for fluid border-radius?

Percentages measure against each dimension separately, so corners come out elliptical on non-square elements. Pixel values stay circular; clamp() is what makes them scale.

How do you pick the three values for a fluid border radius?

Use your existing radius tokens as min and max, and a vw factor that crosses between them at a sensible width. clamp(8px, 2vw, 24px) yields 8px at 400px, about 15px at 768px, and caps at 24px around 1200px.

Does clamp() work in border-radius in all modern browsers?

Yes. clamp() is supported in all current browsers, and border-radius accepts it like any length property. Older-browser fallbacks are covered in our fallback guide.

Get the numbers right before you ship.

Use the CSS Clamp Calculator to generate the min, preferred, and max values for fluid type, spacing, padding, and radius from your own breakpoints.