Frontend Masters Boost RSS Feed https://frontendmasters.com/blog Helping Your Journey to Senior Developer Mon, 23 Jun 2025 14:29:17 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.3 225069128 Understanding CSS corner-shape and the Power of the Superellipse https://frontendmasters.com/blog/understanding-css-corner-shape-and-the-power-of-the-superellipse/ https://frontendmasters.com/blog/understanding-css-corner-shape-and-the-power-of-the-superellipse/#comments Mon, 23 Jun 2025 14:29:16 +0000 https://frontendmasters.com/blog/?p=6270 /* For MathJax */ .article-content p img { display: inline; @media (prefers-color-scheme: dark) { filter: invert(1); } }

The CSS corner-shape property represents one of the most exciting additions to web design’s geometric toolkit in recent years. Extending our ability to control the appearance of corners beyond the simple rounded edges we’ve become accustomed to with border-radius, this seemingly small addition unlocks a world of new possibilities that previously required complex SVG implementations or image-based solutions.

Demo

As of this writing (June 2025), corner-shape is a very new feature with limited browser support, currently only available in Chrome (version M139 and above). The specification may still undergo changes. Try Chrome Canary right now to view these demos.

Before we dive into the advanced capabilities of this property, let’s first understand the foundation it builds upon: the familiar border-radius property that has shaped our corners for over a decade.

The Foundation

The border-radius property gave us the ability to easily create rounded corners on elements. At the max value, using absolute values (like pixels) creates pill shapes, while percentage values create consistent rounded corners. However, any non-zero radius would always create an elliptical curve.

While it is a powerful and useful tool, sometimes we need something… different. This is where the new corner-shape property comes in, expanding our geometric vocabulary beyond just rounded corners.

Introducing corner-shape

The corner-shape property works as a companion to border-radius, where border-radius determines the ‘size’ of the curve, and corner-shape defines how that curve looks.

CSS provides several predefined keywords for corner shapes:

  • round (default): Creates the traditional circular or elliptical corners
  • squircle: A smooth blend between a square and circle
  • scoop: Concave quarters of an ellipse
  • bevel: Straight lines connecting the corner points
  • notch: Creating an inward corner
  • square: Maintains right angles regardless of border-radius (why is this a thing?!)

These keywords enable us to create diverse and visually interesting borders, without resorting to complex implementations, and allow us to easily produce simple geometric shapes like rhombuses, octagons, or plus signs (+).

.rhombus {
  aspect-ratio: 2 / 3;
  border-radius: 50%;
  corner-shape: bevel;
}

.octagon {
  aspect-ratio: 1;
  border-radius: calc(100% / (2 + sqrt(2))); /* ~29% */
  corner-shape: bevel;
}

.plus {
  aspect-ratio: 1;
  border-radius: calc(100% / 3);
  corner-shape: notch;
}

.plus-alt {
  /* rotate to get a X sign */
  rotate: 45deg;
}

In the not-so-distant future, we will also be able to use the corners shorthand to write things more conveniently. Like this:

.rhombus { 
  corners: 50% bevel;
}

We can create even more shapes with squircle and scoop, but we’ll explore those in depth when we discuss Superellipses. For now, let’s talk about using multiple values…

Working with Multiple Values

So far, we’ve used a single value for border-radius, but we can get much more creative. As you may know, border-radius can accept up to eight different values (horizontal and vertical radii for each of the four corners).

This becomes particularly interesting when combined with corner-shape. The interaction between different radius values and corner shapes creates a rich playground for design experimentation.

By using multiple values, we can create additional designs and shapes, like my all time favorite shape – hexagons. Now we can generate perfect hexagons with just a few simple lines of CSS. Using a bevel shape for the corners, and giving different values to the horizontal and vertical radii (50% and 25%).

.hexagon {
  aspect-ratio: cos(30deg);
  border-radius: 50% / 25%;
  corner-shape: bevel;
}

.hexagon-alt {
  aspect-ratio: 1 / cos(30deg);
  border-radius: 25% / 50%;
}

But border-radius is not the only one that can accept multiple values, corner-shape is a shorthand too, and can take up to 4 values, one for each corner. In this way, we can create even more unique shapes.

.shapeA {
  aspect-ratio: 1 / 2;
  border-radius: 40% / 50%;
  corner-shape: bevel squircle squircle bevel;
}
.shapeB {
  aspect-ratio: 1;
  border-radius: 10% 50% 50%;
  corner-shape: round scoop bevel;
  rotate: 45deg;
}
.shapeC {
  aspect-ratio: 1;
  border-radius: 10% 10% 50% 50%;
  corner-shape: round round scoop scoop ;
}

One of these shapes made me think of speech bubbles. We always needed a little help from pseudo-elements (and some hacking) to create an ‘arrow’ at the bottom of the element. Now, we can do it with a simple border-radius.

We can also declare just one specific corner, which can be particularly useful when we want to style just one corner differently, for example, to create space for a counter or a button at the corner of an element.

.container {
  border-radius: 40px;
  corner-top-right-shape: scoop;
}

Animation and Transition of corner-shape

If you clicked the red button in the previous example (good!), you might have noticed that the closing and opening of the element occurs through a transition of the corner-shape. I take advantage of the fact that a notch with a radius of 50% essentially clip the element completely.

Just like the border-radius, you can also animate the corner-shape property or smoothly transition from one shape to another.

The square value, which might seem useless at first glance, is actually very useful in animations and transitions when we want to animate the border to a square shape.

The Power of Superellipse

So far, we’ve explored the predefined keywords of corner-shape, which are great, but there’s an even more powerful option we haven’t discussed yet: the Superellipse! This is arguably more impressive than all the previous options combined, as those keywords are essentially just specific points along the superellipse spectrum. So let’s understand what are superellipses, what is the superellipse function, and how we can use it to fine-tune our borders.

A colorful geometric design featuring lines and curves arranged in a symmetrical pattern, resembling a superellipse with a vibrant gradient from black to neon colors.

As a mathematical concept, the superellipse has existed for about a hundred years, and I love it because someone took something that had existed for centuries (the ellipse formula) and said, “let’s do this differently”. Gabriel Lamé took the formula for an ellipse [x^2 + y^2 = 1] and asked, what happens if we replace the ^2 with something else?! The result: hundred years goes by, his formula is embedded in browsers, making thousands of web developers happier.

Math dudes will comment the actual formula for an ellipse is [x^2/a^2 + y^2/b^2 = 1] but since the [a] and [b] are the axis set by the element’s width and height, we can set [a = b = 1] and get the simplified formula [x^2 + y^2 = 1]

When we replace the ^2 with a variable (n), this variable would now represent the “squareness” of the shape. If ^2 represents a regular circle, then with values greater than ^2, the curve approaches a rectangle, and with values less than ^2, the line starts to straighten. When [n = 1], it means [x^1 + y^1 = 1], which is exactly the same as [x + y = 1], which is actually the formula of a straight line, resulting in a diamond shape. And any number between zero and one gives us a concave shape.

The CSS Superellipse function

But if all this sounds a bit complicated, don’t worry, the CSS folks took care of us, making this function much simpler and way more intuitive. Unlike Lamé’s formula, the CSS superellipse() function takes an argument (let’s call it k) that can be any value, positive or negative. And the way the function works is like this:

  • Zero is the ‘mid-point’, so if we pass 0 to the function, i.e. superellipse(0), we get a straight line, just like the bevel we saw earlier.
  • Any positive number will give us an outward-curved arc, where superellipse(1) is the regular circle, superellipse(2) is our squircle, and as the number increases, the shape will look more like a square, with infinity giving us the square shape.
  • And the same happens with negative numbers. superellipse(-1) gives us a star-like shape, which is the scoop we saw earlier, and the lower the number, the more deeply concave the corner becomes.

Simple, right? But how?!

The CSS function superellipse(k) uses the exponent 2^k to map the value to n. So [n = 2^k], and the complete formula looks like this:

x^(2^k) + y^(2^k)

This calculation format is much more logical and makes the feature more intuitive.

When [k = 0] it means that [n = 2^0] or [n = 1], hence the straight line. If [k = 1] then [n = 2], which is the regular round curve. And if [k > 1] we get [n > 2], resulting in more ‘squircle’ shape. On the other side, when we give the function a negative number, [k < 0], n will always be a number between zero and one, resulting in a concave curve towards the center of the element.

Different Exponents

One limitation of the current superellipse() function is that we can’t pass two variables to it, like superellipse(k, l), to use different exponents for the x and y axes. That would give us the formula [x^(2^k) + y^(2^l) = 1].

If this were possible, we could create some really interesting shapes like this:

A mathematical illustration of a superellipse, depicted with a pink outline on a black background.

Beyond Two Dimensions

While it’s completely outside the scope of this article, if you’ve made it this far, you might be interested to know that the superellipse concept extends to higher dimensions as well. There’s the Superellipsoid that exists in three dimensions, and you can represent a hyperellipsoid in d dimensions using the following formula:

x_1^n + x_2^n + ... + x_d^n = 1

Wrapping up

This article walked us through the evolution from a simple rounded edges to a full geometric vocabulary with the new CSS corner‑shape property. We explored the predefined shapes, and discover how they map directly to points on the superellipse spectrum, and dive into the true power of the superellipse function. We saw how we can mix multiple values to craft wild shapes, how to animate and transition the corners, and how to exploit even the weird edge case to our advantage.

Now it’s your turn: bring these ideas into your own work. Open a new Pen, add a corner‑shape to a simple box or button, and watch how a tiny tweak changes the whole feel of your design. Don’t forget to share your experiments with the community, inspire others with unexpected curves and help drive this bold new CSS feature into everyday use.


I’d like to give special thanks to Noam Rosenthal for reviewing the code and examples, helping refine the ideas, and of course, for authoring the spec for corner-shape and implementing it in chromium.

]]>
https://frontendmasters.com/blog/understanding-css-corner-shape-and-the-power-of-the-superellipse/feed/ 3 6270
Drawing CSS Shapes using corner-shape https://frontendmasters.com/blog/drawing-css-shapes-using-corner-shape/ https://frontendmasters.com/blog/drawing-css-shapes-using-corner-shape/#comments Wed, 18 Jun 2025 17:05:26 +0000 https://frontendmasters.com/blog/?p=6235 We recently got the new shape() function for clip-path which is a game changer for creating CSS shape. Another cool feature is on the way and will soon be available: corner-shape.

I will not call it “new” because it’s something that has been around for quite a while and you can find countless GitHub discussions around it. There is even an 11-year old Github Repo made by Lea Verou with an interactive demo showing a few examples! After all that time, It finally has its own specification and is ready to be implemented and shipped.

At the time of writing, corner-shape is available in Chrome v139 or 136+ with the experimental web features flag turned on, but no other browsers yet.

What is corner-shape?

When you define a border-radius you will get rounded corners. corner-shape allows you to change those rounded corners to something else. It’s in the name; it changes the “shape” of the “corner”.

A graphic displaying different CSS corner shapes: 'round', 'scoop', 'bevel', 'notch', and 'squircle', each in a purple background with white text.

The value round is the default (the classic rounded corners). As you can see above, we have many cool variations. All of this with a simple syntax:

.corner {
  border-radius: 30px;
  corner-shape: round | scoop | bevel | notch | squircle;
}

We can also use the superellipse(K) value that can define all the different variations and more by adjusting the K variable. I will not detail that part as it’s not important for the article but it’s good to know so I invite you to check the (draft) specification for more detail.

Diagram illustrating various 'superellipse()' values for corner shapes with labeled corners and arrows indicating direction. Shows how the corner shape changes with different K values.

Let’s Draw Shapes

Changing the corner shape is good — but how can we draw shapes? The answer is to play with border-radius. Follow along to see all the magic we can do with corner-shape!

Rhombus & Octagon

If you look closely at the example using the bevel value, you will see that we have 8 sides since the corners are diagonal straight lines so we almost have an octagon shape. We simply need to find the exact value for border-radius that gives us 8 equal sides.

I will skip the boring math and give you the final value which is:

border-radius: calc(100%/(2 + sqrt(2)));

Even without being precise, you can approximate the value using trial & error. You will get an octagon when you are close to 29%. The usage of percentage is important because it means the shape is responsive and let’s not forget aspect-ratio: 1 as well.

.octagon {
  border-radius: calc(100%/(2 + sqrt(2)));
  corner-shape: bevel;
  aspect-ratio: 1;
} 

Now what if we keep increasing the radius? We get a Rhombus shape at 50%.

.rhombus {
  border-radius: 50%;
  corner-shape: bevel;
  aspect-ratio: 1;
} 

Some of you might ask if this method is better than what we already have. In my shape collection, you can easily find the code of the above shapes made using clip-path so why another method?

First of all, the syntax is a bit easier than the clip-path one so this can improve the readability of the code as we have fewer values to deal with. But the most important advantage is that we can add a border to the shape! Adding borders to custom shapes is always a nightmare but corner-shape made it easy.

This is logical since, by default, when we add border-radius, the border and other decorations such as box-shadow will follow the rounded corners. It’s still the case even if we change the shape of the corner.

Five shapes with different corner styles labeled: round, scoop, bevel, notch, and squircle, all displayed on a purple background.

Here are the rhombus and octagon shapes with borders:

Note how we can have a border-only version if we keep the background transparent and we can also apply the shape to an image as well. Cool, right?

Hexagon

Do you see how can we achieve a hexagon shape? Try to think about it before reading my explanation.

The trick is to rely on the fact that border-radius accepts vertical and horizontal values, something we always forget about. Let’s take the rhombus shape and decrease the vertical or the horizontal radius.

Do you see that? We have an “almost” hexagon shape. All that is missing is the correct aspect-ratio.

.hexagon {
  border-radius: 50% / 25%; /* OR 25% / 50% */
  corner-shape: bevel;
  aspect-ratio: cos(30deg); /* OR 1/cos(30deg) */
}

We can definitely say that we have the easiest and simplest way to create hexagon shapes!

Triangles

Following the same logic we can create most of the common shapes and triangles aren’t an exception. Again, we can use the Rhombus as a starting point and adjust either the horizontal or the vertical radius like below.

This one can be a bit tricky at first glance because we don’t have the 4 diagonal lines for each corner like the previous shapes but don’t forget that we can use 0 with border-radius which will disable the corresponding corner.

.triangle {
  border-radius: 50% / 100% 100% 0 0; 
  corner-shape: bevel;
} 

From there, we can easily get any kind of triangle by trying the different radius combinations and also playing with aspect-ratio.

Below is a demo with many examples. Try to create some of them before checking my code. It’s the perfect exercise to practice with corner-shape.

The only caveat with triangle shapes is that the border is not perfect. It may sound like a bug but it’s not. I won’t detail the logic behind this but if you want to add a border, you may need a different thickness for one or many sides.

Here is an example with one of the triangle shapes where I am increasing the thickness of the top border a little to have a perfect-looking shape.

As you can see in the code, there is a math formula to get the correct thickness but since it will be a different formula for each triangle shape, I won’t bother you with a boring explanation. Plus you can easily (and rapidly) get a good result with some trial & error. No need to be very precise.

Slanted edge

All the shapes we created rely on percentage values but border-radius accepts length as well, which means we can have elements with variable size but the shape remains static.

Example with a slanted edge where the slant keeps the same size whatever the element width:

The code is a simple as:

.slanted {
  border-top-right-radius: 80px 100%;
  corner-shape: bevel;
}

No need for the shorthand property in this case since only the top-right corner matters. As for the value, I think it’s self-explanatory. Simply notice that there is no / to separate the horizontal and vertical radius when using the longhand properties.

Arrow-like box

Using the same logic we can have an arrow-like box:

.arrow {
  border-radius: 80px / 0 50% 50% 0;
  corner-shape: bevel;
}

Trapezoid & Parallelogram

Also trapezoid & parallelogram shapes:

.trapezoid {
  border-radius: 80px / 100% 0 100% 0;
  corner-shape: bevel;
}
.parallelogram {
  border-radius: 80px / 100% 100% 0 0;
  corner-shape: bevel;
}

Conclusion

Using only the bevel option of corner-shape we were able to create a lot of different shapes easily. All we had to do was to play with border-radius, a well-known property. Not to mention the fact that we can easily add borders and box shadows which is a real game changer compared to shapes created using clip-path or mask.

I will end the article with a last demo where I combine bevel and notch to create an arrow. Yes, you can have a different shape per corner!

What about you? Can you think about a cool shape using corner-shape?

]]>
https://frontendmasters.com/blog/drawing-css-shapes-using-corner-shape/feed/ 8 6235