{"id":6270,"date":"2025-06-23T09:29:16","date_gmt":"2025-06-23T14:29:16","guid":{"rendered":"https:\/\/frontendmasters.com\/blog\/?p=6270"},"modified":"2025-06-23T09:29:17","modified_gmt":"2025-06-23T14:29:17","slug":"understanding-css-corner-shape-and-the-power-of-the-superellipse","status":"publish","type":"post","link":"https:\/\/frontendmasters.com\/blog\/understanding-css-corner-shape-and-the-power-of-the-superellipse\/","title":{"rendered":"Understanding CSS\u00a0corner-shape\u00a0and the Power of the Superellipse"},"content":{"rendered":"\n<style>\n\/* For MathJax *\/\n.article-content p img {\n  display: inline;\n  @media (prefers-color-scheme: dark) {\n    filter: invert(1);\n  }\n}\n<\/style>\n\n\n\n<p>The CSS&nbsp;<code>corner-shape<\/code>&nbsp;property represents one of the most exciting additions to web design&#8217;s geometric toolkit in recent years. Extending our ability to control the appearance of corners beyond the simple rounded edges we&#8217;ve become accustomed to with&nbsp;<code>border-radius<\/code>, this seemingly small addition unlocks a world of new possibilities that previously required complex SVG implementations or image-based solutions.<\/p>\n\n\n\n\t\t<figure class=\"wp-block-jetpack-videopress jetpack-videopress-player aligncenter wp-block-jetpack-videopress--has-max-width\" style=\"max-width: 448px;\" >\n\t\t\t<div class=\"jetpack-videopress-player__wrapper\"> <iframe title=\"VideoPress Video Player\" aria-label='VideoPress Video Player' width='500' height='500' src='https:\/\/videopress.com\/embed\/ngdUKVsV?cover=1&amp;autoPlay=0&amp;controls=1&amp;loop=1&amp;muted=1&amp;persistVolume=0&amp;playsinline=1&amp;preloadContent=metadata&amp;useAverageColor=1&amp;hd=0' frameborder='0' allowfullscreen data-resize-to-parent=\"true\" allow='clipboard-write'><\/iframe><script src='https:\/\/v0.wordpress.com\/js\/next\/videopress-iframe.js?m=1739540970'><\/script><\/div>\n\t\t\t<figcaption><a href=\"https:\/\/codepen.io\/amit_sheen\/pen\/pvJKGov\/5d14d83481ba74eea561f08d81493614\">Demo<\/a><\/figcaption>\n\t\t\t\n\t\t<\/figure>\n\t\t\n\n\n<p class=\"learn-more\">As of this writing (June 2025),&nbsp;<code>corner-shape<\/code>&nbsp;is <strong>a very new feature<\/strong> with limited browser support, currently only available in Chrome (version M139 and above). The specification may still undergo changes. Try <a href=\"https:\/\/www.google.com\/chrome\/canary\/\">Chrome Canary<\/a> right now to view these demos.<\/p>\n\n\n\n<p>Before we dive into the advanced capabilities of this property, let&#8217;s first understand the foundation it builds upon: the familiar&nbsp;<code>border-radius<\/code>&nbsp;property that has shaped our corners for over a decade.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-foundation\"><strong>The Foundation<\/strong><\/h2>\n\n\n\n<p>The&nbsp;<code>border-radius<\/code>&nbsp;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.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_JodvZww\/837098643a428351a0b0d2455713cf55\" src=\"\/\/codepen.io\/anon\/embed\/JodvZww\/837098643a428351a0b0d2455713cf55?height=450&amp;theme-id=47434&amp;slug-hash=JodvZww\/837098643a428351a0b0d2455713cf55&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed JodvZww\/837098643a428351a0b0d2455713cf55\" title=\"CodePen Embed JodvZww\/837098643a428351a0b0d2455713cf55\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>While it is a powerful and useful tool, sometimes we need something&#8230; different. This is where the new&nbsp;<code>corner-shape<\/code>&nbsp;property comes in, expanding our geometric vocabulary beyond just rounded corners.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"introducing-corner-shape\">Introducing&nbsp;<code>corner-shape<\/code><\/h2>\n\n\n\n<p>The&nbsp;<code>corner-shape<\/code>&nbsp;property works as a companion to&nbsp;<code>border-radius<\/code>, where&nbsp;<code>border-radius<\/code>&nbsp;determines the &#8216;size&#8217; of the curve, and&nbsp;<code>corner-shape<\/code>&nbsp;defines how that curve looks.<\/p>\n\n\n\n<p>CSS provides several predefined keywords for corner shapes:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>round<\/code>&nbsp;(default): Creates the traditional circular or elliptical corners<\/li>\n\n\n\n<li><code>squircle<\/code>: A smooth blend between a square and circle<\/li>\n\n\n\n<li><code>scoop<\/code>: Concave quarters of an ellipse<\/li>\n\n\n\n<li><code>bevel<\/code>: Straight lines connecting the corner points<\/li>\n\n\n\n<li><code>notch<\/code>: Creating an inward corner<\/li>\n\n\n\n<li><code>square<\/code>: Maintains right angles regardless of border-radius (why is this a thing?!)<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_XJbqPOp\/9b856108dde46db8b02244980b69016e\" src=\"\/\/codepen.io\/anon\/embed\/XJbqPOp\/9b856108dde46db8b02244980b69016e?height=450&amp;theme-id=47434&amp;slug-hash=XJbqPOp\/9b856108dde46db8b02244980b69016e&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed XJbqPOp\/9b856108dde46db8b02244980b69016e\" title=\"CodePen Embed XJbqPOp\/9b856108dde46db8b02244980b69016e\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>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 (+).<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.rhombus<\/span> {\n  <span class=\"hljs-attribute\">aspect-ratio<\/span>: <span class=\"hljs-number\">2<\/span> \/ <span class=\"hljs-number\">3<\/span>;\n  <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">50%<\/span>;\n  <span class=\"hljs-attribute\">corner-shape<\/span>: bevel;\n}\n\n<span class=\"hljs-selector-class\">.octagon<\/span> {\n  <span class=\"hljs-attribute\">aspect-ratio<\/span>: <span class=\"hljs-number\">1<\/span>;\n  <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-built_in\">calc<\/span>(<span class=\"hljs-number\">100%<\/span> \/ (<span class=\"hljs-number\">2<\/span> + sqrt(<span class=\"hljs-number\">2<\/span>))); <span class=\"hljs-comment\">\/* ~29% *\/<\/span>\n  <span class=\"hljs-attribute\">corner-shape<\/span>: bevel;\n}\n\n<span class=\"hljs-selector-class\">.plus<\/span> {\n  <span class=\"hljs-attribute\">aspect-ratio<\/span>: <span class=\"hljs-number\">1<\/span>;\n  <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-built_in\">calc<\/span>(<span class=\"hljs-number\">100%<\/span> \/ <span class=\"hljs-number\">3<\/span>);\n  <span class=\"hljs-attribute\">corner-shape<\/span>: notch;\n}\n\n<span class=\"hljs-selector-class\">.plus-alt<\/span> {\n  <span class=\"hljs-comment\">\/* rotate to get a X sign *\/<\/span>\n  <span class=\"hljs-attribute\">rotate<\/span>: <span class=\"hljs-number\">45deg<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_VYLdZZd\/bbd001c77bfbebb24e63bbfc4b825b66\" src=\"\/\/codepen.io\/anon\/embed\/VYLdZZd\/bbd001c77bfbebb24e63bbfc4b825b66?height=450&amp;theme-id=47434&amp;slug-hash=VYLdZZd\/bbd001c77bfbebb24e63bbfc4b825b66&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed VYLdZZd\/bbd001c77bfbebb24e63bbfc4b825b66\" title=\"CodePen Embed VYLdZZd\/bbd001c77bfbebb24e63bbfc4b825b66\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<div class=\"wp-block-group learn-more\"><div class=\"wp-block-group__inner-container is-layout-constrained wp-block-group-is-layout-constrained\">\n<p>In the not-so-distant future, we will also be able to use the\u00a0<code>corners<\/code>\u00a0shorthand to write things more conveniently. Like this: <\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.rhombus<\/span> { \n  <span class=\"hljs-attribute\">corners<\/span>: <span class=\"hljs-number\">50%<\/span> bevel;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre><\/div><\/div>\n\n\n\n<p>We can create even more shapes with&nbsp;<code>squircle<\/code>&nbsp;and&nbsp;<code>scoop<\/code>, but we&#8217;ll explore those in depth when we discuss Superellipses. For now, let&#8217;s talk about using multiple values&#8230;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"working-with-multiple-values\"><strong>Working with Multiple Values<\/strong><\/h2>\n\n\n\n<p>So far, we&#8217;ve used a single value for&nbsp;<code>border-radius<\/code>, but we can get much more creative. As you may know,&nbsp;<code>border-radius<\/code>&nbsp;can accept up to eight different values (horizontal and vertical radii for each of the four corners).<\/p>\n\n\n\n<p>This becomes particularly interesting when combined with&nbsp;<code>corner-shape<\/code>. The interaction between different radius values and corner shapes creates a rich playground for design experimentation.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_XJbYrzz\/15f16f64904524d05a35339a16094ac7\" src=\"\/\/codepen.io\/anon\/embed\/XJbYrzz\/15f16f64904524d05a35339a16094ac7?height=450&amp;theme-id=47434&amp;slug-hash=XJbYrzz\/15f16f64904524d05a35339a16094ac7&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed XJbYrzz\/15f16f64904524d05a35339a16094ac7\" title=\"CodePen Embed XJbYrzz\/15f16f64904524d05a35339a16094ac7\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>By using multiple values, we can create additional designs and shapes, like my all time favorite shape &#8211; hexagons. Now we can generate perfect hexagons with just a few simple lines of CSS. Using a <code>bevel<\/code> shape for the corners, and giving different values to the horizontal and vertical radii (50% and 25%).<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.hexagon<\/span> {\n  <span class=\"hljs-attribute\">aspect-ratio<\/span>: <span class=\"hljs-built_in\">cos<\/span>(<span class=\"hljs-number\">30deg<\/span>);\n  <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">50%<\/span> \/ <span class=\"hljs-number\">25%<\/span>;\n  <span class=\"hljs-attribute\">corner-shape<\/span>: bevel;\n}\n\n<span class=\"hljs-selector-class\">.hexagon-alt<\/span> {\n  <span class=\"hljs-attribute\">aspect-ratio<\/span>: <span class=\"hljs-number\">1<\/span> \/ <span class=\"hljs-built_in\">cos<\/span>(<span class=\"hljs-number\">30deg<\/span>);\n  <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">25%<\/span> \/ <span class=\"hljs-number\">50%<\/span>;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_ZYGREvm\/de2c08a57d5718e849f23ce4014b3a6f\" src=\"\/\/codepen.io\/anon\/embed\/ZYGREvm\/de2c08a57d5718e849f23ce4014b3a6f?height=450&amp;theme-id=47434&amp;slug-hash=ZYGREvm\/de2c08a57d5718e849f23ce4014b3a6f&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed ZYGREvm\/de2c08a57d5718e849f23ce4014b3a6f\" title=\"CodePen Embed ZYGREvm\/de2c08a57d5718e849f23ce4014b3a6f\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>But&nbsp;<code>border-radius<\/code>&nbsp;is not the only one that can accept multiple values,&nbsp;<code>corner-shape<\/code>&nbsp;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.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.shapeA<\/span> {\n  <span class=\"hljs-attribute\">aspect-ratio<\/span>: <span class=\"hljs-number\">1<\/span> \/ <span class=\"hljs-number\">2<\/span>;\n  <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">40%<\/span> \/ <span class=\"hljs-number\">50%<\/span>;\n  <span class=\"hljs-attribute\">corner-shape<\/span>: bevel squircle squircle bevel;\n}\n<span class=\"hljs-selector-class\">.shapeB<\/span> {\n  <span class=\"hljs-attribute\">aspect-ratio<\/span>: <span class=\"hljs-number\">1<\/span>;\n  <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">10%<\/span> <span class=\"hljs-number\">50%<\/span> <span class=\"hljs-number\">50%<\/span>;\n  <span class=\"hljs-attribute\">corner-shape<\/span>: round scoop bevel;\n  <span class=\"hljs-attribute\">rotate<\/span>: <span class=\"hljs-number\">45deg<\/span>;\n}\n<span class=\"hljs-selector-class\">.shapeC<\/span> {\n  <span class=\"hljs-attribute\">aspect-ratio<\/span>: <span class=\"hljs-number\">1<\/span>;\n  <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">10%<\/span> <span class=\"hljs-number\">10%<\/span> <span class=\"hljs-number\">50%<\/span> <span class=\"hljs-number\">50%<\/span>;\n  <span class=\"hljs-attribute\">corner-shape<\/span>: round round scoop scoop ;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_EajRNeL\/92167390cfccf21b7a6e3e1624ef21de\" src=\"\/\/codepen.io\/anon\/embed\/EajRNeL\/92167390cfccf21b7a6e3e1624ef21de?height=450&amp;theme-id=47434&amp;slug-hash=EajRNeL\/92167390cfccf21b7a6e3e1624ef21de&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed EajRNeL\/92167390cfccf21b7a6e3e1624ef21de\" title=\"CodePen Embed EajRNeL\/92167390cfccf21b7a6e3e1624ef21de\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>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 &#8216;arrow&#8217; at the bottom of the element. Now, we can do it with a simple&nbsp;<code>border-radius<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_LEVJGNY\/584cd2b4880cb44a259b94709a02ebf5\" src=\"\/\/codepen.io\/anon\/embed\/LEVJGNY\/584cd2b4880cb44a259b94709a02ebf5?height=450&amp;theme-id=47434&amp;slug-hash=LEVJGNY\/584cd2b4880cb44a259b94709a02ebf5&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed LEVJGNY\/584cd2b4880cb44a259b94709a02ebf5\" title=\"CodePen Embed LEVJGNY\/584cd2b4880cb44a259b94709a02ebf5\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>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.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-class\">.container<\/span> {\n  <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">40px<\/span>;\n  <span class=\"hljs-attribute\">corner-top-right-shape<\/span>: scoop;\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_OPVERed\/e3894bfcee953823e4f3f957570d8a9e\" src=\"\/\/codepen.io\/anon\/embed\/OPVERed\/e3894bfcee953823e4f3f957570d8a9e?height=450&amp;theme-id=47434&amp;slug-hash=OPVERed\/e3894bfcee953823e4f3f957570d8a9e&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed OPVERed\/e3894bfcee953823e4f3f957570d8a9e\" title=\"CodePen Embed OPVERed\/e3894bfcee953823e4f3f957570d8a9e\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"animation-and-transition-of-corner-shape\"><strong>Animation and Transition of corner-shape<\/strong><\/h2>\n\n\n\n<p>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&nbsp;<code>corner-shape<\/code>. I take advantage of the fact that a&nbsp;<code>notch<\/code>&nbsp;with a radius of&nbsp;<code>50%<\/code>&nbsp;essentially clip the element completely.<\/p>\n\n\n\n<p>Just like the&nbsp;<code>border-radius<\/code>, you can also animate the&nbsp;<code>corner-shape<\/code>&nbsp;property or smoothly transition from one shape to another.<\/p>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_emNKKQG\/02d09eef94a14fccca933d82865ce881\" src=\"\/\/codepen.io\/anon\/embed\/emNKKQG\/02d09eef94a14fccca933d82865ce881?height=450&amp;theme-id=47434&amp;slug-hash=emNKKQG\/02d09eef94a14fccca933d82865ce881&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed emNKKQG\/02d09eef94a14fccca933d82865ce881\" title=\"CodePen Embed emNKKQG\/02d09eef94a14fccca933d82865ce881\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_wBaXXab\/fa315e386c81e2802de18d99c3f70c3c\" src=\"\/\/codepen.io\/anon\/embed\/wBaXXab\/fa315e386c81e2802de18d99c3f70c3c?height=450&amp;theme-id=47434&amp;slug-hash=wBaXXab\/fa315e386c81e2802de18d99c3f70c3c&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed wBaXXab\/fa315e386c81e2802de18d99c3f70c3c\" title=\"CodePen Embed wBaXXab\/fa315e386c81e2802de18d99c3f70c3c\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p class=\"learn-more\">The&nbsp;<code>square<\/code>&nbsp;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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"the-power-of-superellipse\">The Power of Superellipse<\/h2>\n\n\n\n<p>So far, we&#8217;ve explored the predefined keywords of&nbsp;<code>corner-shape<\/code>, which are great, but there&#8217;s an even more powerful option we haven&#8217;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&#8217;s understand what are superellipses, what is the superellipse function, and how we can use it to fine-tune our borders.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"820\" height=\"620\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/06\/vihaX6Fo.png?resize=820%2C620&#038;ssl=1\" alt=\"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.\" class=\"wp-image-6273\" srcset=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/06\/vihaX6Fo.png?w=820&amp;ssl=1 820w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/06\/vihaX6Fo.png?resize=300%2C227&amp;ssl=1 300w, https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/06\/vihaX6Fo.png?resize=768%2C581&amp;ssl=1 768w\" sizes=\"auto, (max-width: 820px) 100vw, 820px\" \/><\/figure>\n\n\n\n<p>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, &#8220;let&#8217;s do this differently&#8221;.&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Gabriel_Lam%C3%A9\">Gabriel Lam\u00e9<\/a>&nbsp;took the formula for an ellipse <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bx%5E2+%2B+y%5E2+%3D+1%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[x^2 + y^2 = 1]\" class=\"latex\" \/> and asked, what happens if we replace the <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5E2&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"^2\" class=\"latex\" \/> with something else?! The result: hundred years goes by, his formula is embedded in browsers, making thousands of web developers happier.<\/p>\n\n\n\n<p class=\"learn-more\">Math dudes will comment the actual formula for an ellipse is <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bx%5E2%2Fa%5E2+%2B+y%5E2%2Fb%5E2+%3D+1%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[x^2\/a^2 + y^2\/b^2 = 1]\" class=\"latex\" \/> but since the <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Ba%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[a]\" class=\"latex\" \/> and <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bb%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[b]\" class=\"latex\" \/> are the axis set by the element\u2019s width and height, we can set <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Ba+%3D+b+%3D+1%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[a = b = 1]\" class=\"latex\" \/> and get the simplified formula <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bx%5E2+%2B+y%5E2+%3D+1%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[x^2 + y^2 = 1]\" class=\"latex\" \/><\/p>\n\n\n\n<p>When we replace the <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5E2&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"^2\" class=\"latex\" \/> with a variable (<img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=n&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"n\" class=\"latex\" \/>), this variable would now represent the &#8220;squareness&#8221; of the shape. If <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5E2&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"^2\" class=\"latex\" \/> represents a regular circle, then with values greater than <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5E2&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"^2\" class=\"latex\" \/>, the curve approaches a rectangle, and with values less than <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5E2&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"^2\" class=\"latex\" \/>, the line starts to straighten. When <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bn+%3D+1%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[n = 1]\" class=\"latex\" \/>, it means <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bx%5E1+%2B+y%5E1+%3D+1%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[x^1 + y^1 = 1]\" class=\"latex\" \/>, which is exactly the same as <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bx+%2B+y+%3D+1%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[x + y = 1]\" class=\"latex\" \/>, 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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The CSS Superellipse function<\/h2>\n\n\n\n<p>But if all this sounds a bit complicated, don&#8217;t worry, the CSS folks took care of us, making this function much simpler and way more intuitive. Unlike Lam\u00e9&#8217;s formula, the CSS&nbsp;<code>superellipse()<\/code>&nbsp;function takes an argument (let&#8217;s call it <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=k&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"k\" class=\"latex\" \/>) that can be any value, positive or negative. And the way the function works is like this:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Zero is the &#8216;mid-point&#8217;, so if we pass 0 to the function, i.e.&nbsp;<code>superellipse(0)<\/code>, we get a straight line, just like the&nbsp;<code>bevel<\/code>&nbsp;we saw earlier.<\/li>\n\n\n\n<li>Any positive number will give us an outward-curved arc, where&nbsp;<code>superellipse(1)<\/code>&nbsp;is the regular circle,&nbsp;<code>superellipse(2)<\/code>&nbsp;is our squircle, and as the number increases, the shape will look more like a square, with&nbsp;<code>infinity<\/code>&nbsp;giving us the&nbsp;<code>square<\/code>&nbsp;shape.<\/li>\n\n\n\n<li>And the same happens with negative numbers.&nbsp;<code>superellipse(-1)<\/code>&nbsp;gives us a star-like shape, which is the&nbsp;<code>scoop<\/code>&nbsp;we saw earlier, and the lower the number, the more deeply concave the corner becomes.<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper\"><iframe id=\"cp_embed_qEdKoNv\/182bf68a571bffc491c1209e2b0ae75a\" src=\"\/\/codepen.io\/anon\/embed\/qEdKoNv\/182bf68a571bffc491c1209e2b0ae75a?height=450&amp;theme-id=47434&amp;slug-hash=qEdKoNv\/182bf68a571bffc491c1209e2b0ae75a&amp;default-tab=result\" height=\"450\" scrolling=\"no\" frameborder=\"0\" allowfullscreen allowpaymentrequest name=\"CodePen Embed qEdKoNv\/182bf68a571bffc491c1209e2b0ae75a\" title=\"CodePen Embed qEdKoNv\/182bf68a571bffc491c1209e2b0ae75a\" class=\"cp_embed_iframe\" style=\"width:100%;overflow:hidden\">CodePen Embed Fallback<\/iframe><\/div>\n\n\n\n<p>Simple, right? But how?!<\/p>\n\n\n\n<p>The CSS function <code>superellipse(k)<\/code> uses the exponent <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=2%5Ek&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"2^k\" class=\"latex\" \/> to map the value to <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=n&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"n\" class=\"latex\" \/>. So <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bn+%3D+2%5Ek%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[n = 2^k]\" class=\"latex\" \/>, and the complete formula looks like this:<\/p>\n\n\n\n<p>\u200b<img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=x%5E%282%5Ek%29+%2B+y%5E%282%5Ek%29&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"x^(2^k) + y^(2^k)\" class=\"latex\" \/><\/p>\n\n\n\n<p>This calculation format is much more logical and makes the feature more intuitive.<\/p>\n\n\n\n<p>When <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bk+%3D+0%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[k = 0]\" class=\"latex\" \/> it means that <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bn+%3D+2%5E0%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[n = 2^0]\" class=\"latex\" \/> or <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bn+%3D+1%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[n = 1]\" class=\"latex\" \/>, hence the straight line. If <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bk+%3D+1%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[k = 1]\" class=\"latex\" \/> then <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bn+%3D+2%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[n = 2]\" class=\"latex\" \/>, which is the regular round curve. And if <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bk+%3E+1%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[k &gt; 1]\" class=\"latex\" \/> we get <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bn+%3E+2%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[n &gt; 2]\" class=\"latex\" \/>, resulting in more &#8216;squircle&#8217; shape. On the other side, when we give the function a negative number, <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bk+%3C+0%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[k &lt; 0]\" class=\"latex\" \/>, <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=n&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"n\" class=\"latex\" \/> will always be a number between zero and one, resulting in a concave curve towards the center of the element.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"different-exponents\">Different Exponents<\/h2>\n\n\n\n<p>One limitation of the current&nbsp;<code>superellipse()<\/code>&nbsp;function is that we can&#8217;t pass two variables to it, like&nbsp;<code>superellipse(k, l)<\/code>, to use different exponents for the <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=x&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"x\" class=\"latex\" \/> and <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=y&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"y\" class=\"latex\" \/> axes. That would give us the formula <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=%5Bx%5E%282%5Ek%29+%2B+y%5E%282%5El%29+%3D+1%5D&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"[x^(2^k) + y^(2^l) = 1]\" class=\"latex\" \/>.<\/p>\n\n\n\n<p>If this were possible, we could create some really interesting shapes like this:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"233\" src=\"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/06\/tmLuDN5Q.png?resize=300%2C233&#038;ssl=1\" alt=\"A mathematical illustration of a superellipse, depicted with a pink outline on a black background.\" class=\"wp-image-6290\" style=\"width:312px;height:auto\"\/><\/figure>\n<\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"beyond-two-dimensions\"><strong>Beyond Two Dimensions<\/strong><\/h2>\n\n\n\n<p>While it&#8217;s completely outside the scope of this article, if you&#8217;ve made it this far, you might be interested to know that the superellipse concept extends to higher dimensions as well. There&#8217;s the&nbsp;<a href=\"https:\/\/en.wikipedia.org\/wiki\/Superellipsoid\">Superellipsoid<\/a>&nbsp;that exists in three dimensions, and you can represent a hyperellipsoid in <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=d&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"d\" class=\"latex\" \/> dimensions using the following formula:<\/p>\n\n\n\n<p>\u200b <img decoding=\"async\" src=\"https:\/\/s0.wp.com\/latex.php?latex=x_1%5En+%2B+x_2%5En+%2B+...+%2B+x_d%5En+%3D+1&#038;bg=ffffff&#038;fg=000&#038;s=0&#038;c=20201002\" alt=\"x_1^n + x_2^n + ... + x_d^n = 1\" class=\"latex\" \/><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"wrapping-up\">Wrapping up<\/h2>\n\n\n\n<p>This article walked us through the evolution from a simple rounded edges to a full geometric vocabulary with the new CSS&nbsp;<code>corner\u2011shape<\/code>&nbsp;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.<\/p>\n\n\n\n<p>Now it\u2019s your turn: bring these ideas into your own work. <a href=\"https:\/\/pen.new\">Open a new Pen<\/a>, add a&nbsp;<code>corner\u2011shape<\/code>&nbsp;to a simple box or button, and watch how a tiny tweak changes the whole feel of your design. Don\u2019t forget to share your experiments with the community, inspire others with unexpected curves and help drive this bold new CSS feature into everyday use.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"learn-more\">I&#8217;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&nbsp;<a href=\"https:\/\/drafts.csswg.org\/css-borders-4\/#corner-shaping\">spec for <code>corner-shape<\/code><\/a>&nbsp;and implementing it in chromium.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The CSS corner-shape property (very new! only in Chrome Canary!) is useful in basic use cases, for advanced shape making, and the superellipse() function is *extra* powerful.<\/p>\n","protected":false},"author":27,"featured_media":6317,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"sig_custom_text":"","sig_image_type":"featured-image","sig_custom_image":0,"sig_is_disabled":false,"inline_featured_image":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[355,7],"class_list":["post-6270","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-post","tag-corner-shape","tag-css"],"acf":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/frontendmasters.com\/blog\/wp-content\/uploads\/2025\/06\/Understanding-CSS-corner-shape-and-the-Power-of-the-Superellipse.jpg?fit=1140%2C676&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/6270","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/comments?post=6270"}],"version-history":[{"count":23,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/6270\/revisions"}],"predecessor-version":[{"id":6319,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/posts\/6270\/revisions\/6319"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media\/6317"}],"wp:attachment":[{"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/media?parent=6270"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/categories?post=6270"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/frontendmasters.com\/blog\/wp-json\/wp\/v2\/tags?post=6270"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}