Ronalds Vilciņš

Getting border-radius right on nested elements

Give a card and its inner panel the same border-radius and the result often looks wrong. The CSS values match, but the curves do not: the inner corner sits closer to the center and needs a smaller radius.

The gap belongs in the calculation

For concentric circular corners, subtract the space between the elements from the outer radius:

--outer-radius: 1em;
--padding: 0.5em;
--inner-radius: calc(var(--outer-radius) - var(--padding));

The same relationship appears in a concrete example:

.inner {
    width: 5em;
    height: 5em;
    background: black;
    border-radius: 1em;
}
 
.outer {
    display: inline-block;
    background: lightblue;
    padding: 3em;
    border-radius: 4em;
}

The outer radius is 4em, the gap is 3em, and the inner radius is therefore 1em.

Store two tokens or calculate one

Separate inner and outer radius tokens give a designer explicit control. They also create more values that must stay synchronized.

With consistent padding, a calculated property is usually easier to maintain. Change the outer radius or gap and the inner curve follows automatically.

Where I use this

It is a geometric starting point, not a law. Non-uniform padding, elliptical radii, borders, and deliberately exaggerated shapes may need visual adjustment.

A reusable custom property

:root {
  --base-radius: 1em;
  --nested-radius: calc(var(--base-radius) - var(--padding));
}

Make sure the calculation cannot produce an unwanted negative result when the gap exceeds the radius. For ordinary nested cards, the rule I keep in mind is simple: the difference between the two radii should match the gap between the two edges.

Enjoyed reading this?

If you found this article helpful, consider supporting my writing. Every little bit helps keep this blog going.

← Back to all articles