The number is not enough

A border-radius is just a number. A number can't describe how a corner should feel.

The same 12px looks generous on a small button and almost flat on a wide card. Place a rounded element inside another rounded element, give them the same radius, and the corners still won't line up.

CSS
.button, .card { border-radius: 12px; } /* same number, different corner */

Roundness is relative. Against a small element a radius reads soft, against a large one it nearly disappears, and inside another rounded element it has to bend around the gap. The number never moves. Everything around it does.

Most design systems define radius tokens. Far fewer define the relationships between them.

buttoninputcarddrawer
Same radius, different weight.

Size is the part you judge by eye. Nesting is the part you can calculate, and it is where many interfaces break.

Buttons want a decision

Buttons expose this fast, because their height leaves less room for ambiguity. A larger radius is not automatically cleaner. At small sizes, the corner starts to compete with the button shape itself. Push it far enough and the button wants to become a pill.

pill
A button wants a clear shape.

The trap is the middle. A value near half the height, say 14px on a 40px button, doesn't commit. Too round to read as a precise rounded rectangle, not round enough to read as an intentional pill, so it looks swollen instead of soft. A button reads better when the shape is clear: a controlled rounded rectangle, or a pill.

CSS
.button {
  height: 40px;
  border-radius: 10px;
}

.button--almost-pill {
  border-radius: 14px;
}

.button--pill {
  border-radius: 999px;
}

Nested corners

The common failure is one element rounded inside another: a card at 12px, an image inside it, 8px of padding.

It passes review, then looks wrong on screen. Nested corners need a shared center. The inner corner is not another 12px corner placed inside the card. It is the same corner moved inward by the gap.1

That is why, for round corners, the inner radius is the outer radius minus the gap. The gap is everything between the two curves: padding, border, and any intentional spacing.

12 minus 8 equals 4

The formula gives you concentric, not finished. At small radii a strictly concentric inner corner can read a little tight, so a pixel or two more often looks better even when the math disagrees. The number gets you to concentric, your eye takes it the rest of the way. In the demo below, the math lands on 4px. To my eye 6px sits better.

Concentric at 4, balanced at 6.

If the gap is bigger than the radius, the inner corner is square. Once you see it, you start noticing it everywhere.

Borders count as gap

A border is not decoration outside the math. It consumes space between the outer and inner curve. Stack a bordered child inside a padded card and the border joins the padding as part of the gap.

drifting
The border is part of the gap.

Everything between the two curves is the gap, padding and border together. With a 16px outer radius, 8px of padding, and a 1px border, the inner radius is 7px, not 8. Use 8 and you only subtracted the padding. Concentric starts at 7; your eye can take it from there.

CSS
.inner { border-radius: calc(16px - 1px - 8px); }
concentric
Concentric at 7, balanced at 10.

Make the relationship explicit

A system needs two things: a scale that sets the outer radius, and a rule that derives the inner one. Tokens give you the scale. They do nothing for the rule.

A scale reads cleaner when size and corner softness move together.

This is the practical rule. The inner radius is the parent's radius minus the full gap, border and padding both.

CSS
.card__inner {
  border-radius: calc(var(--radius) - var(--border) - var(--pad));
}

Write the relationship, not the result. A 12px card with a 1px border and 8px padding lands on 3px today, but you never typed 3. Change the padding and the corner follows on its own. That is the whole point: hold onto the formula, not the number it happens to produce.

The rule depends on shape

The subtraction works because the default corner is a quarter circle. Offset a circle inward and you get a smaller circle. That is a fact about circles, not corners.

Round was the only corner for so long that nobody clocked it as a choice. Current Chromium corner-shape support makes the assumption visible.

CSS
.card {
  border-radius: 12px;
}

@supports (corner-shape: squircle) {
  .card {
    corner-shape: squircle;
  }
}

The border-radius property still sets how big the corner is. corner-shape sets the curve that fills it.2 round is the arc every example above assumes. squircle is a superellipse, a curve that spreads its bend differently than a circle.

A superellipse does not offset to a smaller superellipse the way a circle does. Subtract the gap and the inner corner no longer traces the outer one.

The CSS compiles. The numbers look right. The corners drift. There is an open CSSWG issue about a superellipse value with inner and outer symmetry, because the plain one does not nest cleanly.3

SwiftUI already has ConcentricRectangle for this.4 CSS does not. For now the squircle part is a forecast, not a recipe.

The formula was always a floor, not a finish. Squircles take the floor away. This time there is no simple number that lands. You judge it and ship the least-wrong one.

What to keep in mind

A radius is not a standalone decision. It changes with size, spacing, borders, and the curve itself.

Size the radius to the element. A button, a card, and a panel should not blindly share one token. On small controls, bad radius choices show up faster: too round to feel precise, not round enough to feel intentional.

For nested round corners, derive the inner radius. Outer radius minus the full gap, with the border counted as part of that gap.

Then look. The formula gets you to a clean relationship, not a finished design. Your eye decides the final value, often a pixel or two past the math.

Drop the formula when you change the curve. With corner-shape, subtraction no longer guarantees a clean nest. Judge the result and ship the least-wrong one.

Gate corner-shape behind @supports. Fall back to round corners everywhere else.