An Interesting Limitation of CSS Custom Properties
As soon as I read my teammate Paul’s explanation of The Math Behind Nesting Rounded Corners, I wanted to recreate it using custom properties and calc.
I thought I’d be able to do something like this:
:root {
--radius: 1em;
--padding: 0.375em;
}
.container {
border-radius: max(var(--radius), 0em);
padding: var(--padding);
}
.container .container {
--radius: calc(var(--radius) - var(--padding));
}Code language: CSS (css)
But that doesn’t work. It creates what the Custom Properties specification calls a “dependency cycle,” where the value of --radius is dependent on itself.
I tried working around this using CSS counters, but as of this writing those don’t work with calc. I also tried setting --radius using @property with inherits: true, but the result was the same as before.
So best solution I’ve come up with is to manually iterate a separate property:
:root {
--radius: 1em;
--padding: 0.375em;
}
.container {
border-radius: max(calc(var(--radius) - var(--padding) * var(--depth, 0)), 0em);
padding: var(--padding);
}
.container .container {
--depth: 1;
}
.container .container .container {
--depth: 2;
}
.container .container .container .container {
--depth: 3;
}Code language: CSS (css)
Here are those styles in action:
It’s kind of a bummer having to guess how many levels of nesting you’ll need, but it should be manageable for smaller values like border radii.
There’s already some talk of new CSS features that would simplify this sort of thing. I’m sure we’ll have a more elegant solution sooner or later.

Tyler Sticka has over 20 years of experience designing interfaces for the web and beyond. He co-owns Cloud Four, where he provides multidisciplinary creative direction for a variety of organizations. He’s also an artist, writer, speaker and developer. You can follow Tyler on his personal site, Mastodon or Bluesky.
