Drawing CSS Shapes using corner-shape

Temani Afif Temani Afif on

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;
}Code language: CSS (css)

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)));Code language: CSS (css)

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;
} Code language: CSS (css)

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;
} Code language: CSS (css)

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) */
}Code language: CSS (css)

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;
} Code language: CSS (css)

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;
}Code language: CSS (css)

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;
}Code language: CSS (css)

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;
}Code language: CSS (css)

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?

Need front-end development training?

Frontend Masters logo

Frontend Masters is the best place to grow in your career as a developer. We have courses on all the most important front-end technologies and beyond, from React to CSS, to backend with Node.js and Full Stack.

7-Day Free Trial

Leave a Reply

Your email address will not be published. Required fields are marked *

Did you know?

Frontend Masters Donates to open source projects. $363,806 contributed to date.