How to nest rounded corners
Sep 18, 2026 · Interface · 3 min read
Put a rounded image inside a rounded card, give both the same radius, and something feels off. Most people cannot say what, but they notice. The corners look pinched, the frame looks thicker at the corners than along the edges, and the whole component reads as slightly cheap.
The cause is geometry. A rounded corner is a quarter circle. When two quarter circles with the same radius sit inside each other, their centers are in different places, so the gap between the curves is not constant. It swells at the corner and shrinks along the straight edges. Your eye reads that swelling as a mistake.
The rule
Nested corners should share a center. Then the gap between the two curves stays the same all the way around, exactly like the straight edges.
inner radius = outer radius - paddingIf the card has a 22px radius and 6px of padding, the image inside gets 16px. That is the exact setup on the gallery cards of this site.
Writing it in CSS
Hard-coding the inner value works until someone changes the padding. Tie the two together with custom properties so they can never drift apart.
.card {
--radius: 22px;
--pad: 6px;
padding: var(--pad);
border-radius: var(--radius);
}
.card > .media {
/* Never below zero, even when the padding is larger than the radius. */
border-radius: max(0px, calc(var(--radius) - var(--pad)));
}The max() matters. Once the padding is as large as the outer radius, the inner corner should simply be square. A negative radius is ignored by the browser, which quietly falls back to the old value and brings the bug back.
Borders count as distance too
If the outer element has a border, the space between the curves is the padding plus the border width. Subtract both:
inner radius = outer radius - border width - paddingShadows and outlines do not count. They are drawn outside the box and do not move the inner edge.
Pills solve themselves
A pill is an element whose radius is half its height. Inside a pill, a smaller pill with the same padding on every side is automatically concentric: its height is the outer height minus twice the padding, so half of it is exactly the outer radius minus the padding. This is why border-radius: 999px on both a segmented control and its sliding thumb always looks right.
Three levels deep
The rule chains. A dialog at 24px, a panel inside it with 8px of padding at 16px, and a button inside that with 6px of padding at 10px. Every step subtracts its own padding. If a level gets so small that the radius drops below about 4px, switch to square corners on purpose instead of letting a 1px curve look like an accident.
Checklist
- Inner radius equals outer radius minus padding (and minus the border, if any).
- The subtraction is wrapped in
max(0px, ...). - Radius and padding live in shared tokens or custom properties, not separate magic numbers.
- Pills inside pills use a full radius on both.
- Very small inner radii are replaced with square corners on purpose.
This piece expands on the Interface rules in my cheat sheet, where every rule has a live example.
Keep readingWhy centered icons look off-centerOptical alignment, icon stroke weight and uneven padding: three places where correct numbers produce wrong-looking UI.