Let's say you drive a car, and the road makes a turn of 90 degrees, and it has the shape of an ideal circle inscribed in a right angle. As a driver, you will feel this turn as very sharp and in some way even dangerous. But if the road starts to curve in a smoother way, giving you time to slightly turn the wheel, then the turn can become even sharper, but by then you have already lost speed in the process of turning. (That's maybe why I don't like cloverleaf interchanges, compared with smooth ones, but this is another story.) So our eyes prefer smooth curves that change dynamically through the turn, rather than mechanical ones.
No wonder Apple, which is crazy about design and curves, has been using the "squircle" shape in their products for a long time: they wanted a more lively shape than a plain rounded corner gives. Did you know that Nokia phone buttons have a squircle shape too?
And finally all this luxury is becoming available in CSS. For now it is available only in Chromium-based browsers (Chrome and Edge from version 139), but if you want to use it in your design today, you can, at least as a graceful degradation. Or even without degradation, but with some quirks.
Radius vs corner-shape
Long story short, I wanted to use this new property and found out that if I just put in CSS
.card {
border-radius: 1rem;
corner-shape: squircle;
}
nothing good will happen, because visually border-radius with 1rem has a different size than a squircle with 1rem. Look at this picture.
It's a big card with border-radius: 7rem and corner-shape: superellipse(3.9), but on the left, corner-shape is disabled (or, just not supported by the browser). The difference is huge.
I mean, if the superellipse is not equal to 1, then corner-shape is not equal to border-radius, and to achieve the same visual effect, you need to adjust the values.
Before I go to the solution, let's talk a bit about this unusual property.
Superellipse, or how curvature continues
I don't want to go deeply into math (for this I recommend you to read the article Understanding CSS corner-shape and the Power of the Superellipse, it has a detailed explanation), I'll just be brief and show the idea.
This is a value that is not a line or some stable constant, but a function that you call with a parameter. That parameter defines the exponent: how much of this type of acceleration the curve should have.
I would say, in reality, if the number is greater than 1, then there is a kind of deceleration at first (remember my example with the road), but then the road goes steep and the curve is sharper. If the number is less than 1, then the curve makes the turn very fast right at the start and then goes gentle.
If the number is equal to 0, the curve is a straight line. Finally, if the number is less than 0, then the curve is concave with the same magnitude as it was with the positive value. But let's say the minimum reasonable value of the superellipse is -3, and the maximum is 5. Notice, the center of these coordinates is a circle, which is equal to 1 (-4 down / +4 up).
Why reasonable? Because if you go beyond these values, it will be hard to see the difference. The formula of superellipse(n) uses the exponent 2^n, so the function of how the curve is drawn is x^(2^n) + y^(2^n) = 1. There is no reason to calculate the curvature that is impossible to see with the naked eye, and for the two corner cases the corner-shape specification already gives us presets: notch and square, which correspond to -Infinity and +Infinity respectively.
Let's see all presets of corner-shape in the value of superellipse(n):
-
notch: -Infinity (absolutely concave, just a square with a cut corner) -
scoop: -1 (concave, just a regular scoop, which fits the squircle) -
bevel: 0 (flat, just a line, no curvature) -
round: 1 (circle, the same as border-radius) -
squircle: 2 (convex, "Apple-style" squircle) -
square: +Infinity (absolutely convex, just a regular square)
Funny to know that:
.element {
/* the same */
corner-shape: superellipse(-infinity);
corner-shape: notch;
/* the same */
corner-shape: superellipse(infinity);
corner-shape: square;
/* the same */
corner-shape: superellipse(0);
corner-shape: bevel;
/* the same */
corner-shape: superellipse(2);
corner-shape: squircle;
/* doesn't make sense, if it's not a dynamic value, just use border-radius */
corner-shape: superellipse(1);
corner-shape: round;
}
Fallback or exact fallback
Finally, about fallback. I've made a corner shape generator
👉 https://a-dev.github.io/probes/corner-shape/
And my main idea was not only an interface to find a beautiful shape to fit your design, but also to generate a fallback for browsers that don't support this property.
Look at the screenshot below.
It's the same card, but that's how the CSS looks:
.card {
border-radius: 1.237rem;
}
@supports (corner-shape: superellipse(3.9)) {
.card {
border-radius: 7rem;
corner-shape: superellipse(3.9);
}
}
As you can see, it's very important to use @supports, because the border-radius value is drastically different, but the result still looks similar. Looks great, doesn't it?
For ~90% of cases this is enough. If you want to make buttons, inputs, or other UI elements better looking, you can easily use this approach. And while browsers don't support this property, users will just see the usual border-radius.
If you want to use corner shapes with a value less than 1, you already need to use what I call an 'exact fallback', that creates a clip-path with exactly the same shape. It's not a perfect solution: first, it's more code, and second, it cuts off box-shadow, outline, etc. It has its own quirks.
The math around this is not trivial, you can read more about it in the docs (thanks Claude/OpenAI for this description and help in the implementation).
That's it. Choose the shape you like, copy the code and go curve!
P.S., or how to architect this CSS
Not long ago I developed what I called a CSS methodology to work with CSS Modules in the modern world (not every project is ready to use Tailwind, sometimes we want good old CSS), and in this methodology it is very easy to use 'atoms' like these corner shapes in your project, however big and complex it is.
Read more in Atoms, layers, types, tokens: a new CSS methodology built on CSS Modules, and in one of my open source projects I use it in this way: shape.module.css.


Top comments (0)