superellipse()

Saleh Mubashar on

The superellipse() function in CSS works with the corner-shape property to control the curvature of an element’s corners. You can set it directly, like superellipse(1), or use keywords, such as round, squircle, or scoop, which are basically preset values.

.box { 
  border-radius: 25px;
  corner-shape: superellipse(0); /* equal to 'bevel'
}

Syntax

superellipse(): superellipse( <number [-∞,∞]> | infinity | -infinity )

The superellipse() function takes a single number (let’s call it K) and maps it to a specific type of curve:

  • K=0 gives you a completely straight cut, basically a bevel.
  • Positive values make the corner curve outward. superellipse(1) is a normal rounded corner, superellipse(2) is a squircle, and as k gets larger, the corner starts to behave more like a square.
  • Negative values flip the curve inward. For example, superellipse(-1) creates a scooped corner, and even lower values pull the curve even deeper toward the element’s center.
Three orange boxes comparing superellipse when it is set to zero, 2, and -1 respectively;

Values

The superellipse() function accepts numeric values, from negative infinity to positive infinity.

ValueWhat it doesKeyword equivalent
superellipse(1)The regular rounded corner you already know from border-radius.round (default)
superellipse(2)A combination of a square and a circle, as the name suggests.squircle
superellipse(infinity)Keeps the corner perfectly right-angled, even if a radius is applied.square
superellipse(0)Cuts the corner diagonally, producing a flat edge.Let’s you pick your own curve using a custom value for k.
superellipse(-1)Creates a concave (inward) quarter ellipse.scoop
superellipse(-infinity)Produces a sharp inward corner.notch
superellipse(k)Lets you pick your own curve using a custom value for k.N/A.

Amit Sheen has a great demo that helps visualize the values:

What’s going on behind the scenes

You don’t need a math degree to use superellipse(), but it is pretty cool to know what the browser is actually doing when you pass a value like superellipse(2) or superellipse(-1). Under the hood, the superellipse is just a remix of the ellipse equation. Normally, an ellipse is defined as a mathematical formula like this:

X squared plus Y squared equals 1.

(Technically, it’s a little different. But since CSS scales the axes automatically based on the box’s width and height, we can treat a and b as 1 and refactor things a bit). With superellipse(), the formula becomes:

X squared to the K power plus Y squared to the K power equals 1.

The K variable is the superellipse parameter. For example, when K=0, the equation reduces to a line, resulting in a bevel shape. Similarly, when K=1, we get the standard circle equation, creating rounded corners. You get the idea.

Here’s a demo that explores the full superellipse() spectrum:

It’s worth noting that superellipse() only takes a single parameter, so the same value of K is applied to both x and y. It would be pretty neat to set them separately as that opens up the possibility to create a bunch of unique shapes.

Basic usage

If you’ve explored the corner-shape property, you’ll know that it lets you control the style of an element’s corners using keywords like round, squircle, bevel, or scoop. These keywords are essentially shortcuts for specific predefined curves.

.box {
  border-radius: 30px;
  corner-shape: superellipse(-1); /* concave "scoop" style */
}

With superellipse(), you can use custom numeric values, like 0.8 or 1.5, for more fine-grained control.

.box {
  border-radius: 30px;
  corner-shape: superellipse(0.5); /* a curve between bevel and round */
}

Note: Even when using superellipse(), all radii still follow the usual border-radius collision rules. If opposite corners would overlap (for example, with very large radii), the browser automatically scales things down so the shapes fit without crossing.

Working with multiple values

When you use superellipse() with the corner-shape property, it follows the same 1–4-value syntax you see with border-radius. A single value will be applied to all four corners, two values split the top and bottom, and four values let you style each corner independently in a clockwise direction starting with the element’s top-left corner. You can read more about the four-value syntax in corner-shape.

Here’s what that looks like:

.card {
  border-radius: 30px;
  corner-shape: superellipse(0) superellipse(1) superellipse(2) superellipse(-1);

  /* Equivalent to: */
  corner-top-left-shape: 0;
  corner-top-right-shape: 1;
  corner-bottom-right-shape: 2;
  corner-bottom-left-shape: -1;
}

Animations and transitions

The superellipse() function can be animated just like other corner-shape values, because they are simply aliases for the superellipse() function.

For example:

.box {
  border-radius: 40px;
  transition: corner-shape 0.4s ease;
}

.box:hover {
  corner-shape: superellipse(1.8);
}

…or an animation between numeric K values:

@keyframes pulse {
  0%   { corner-shape: superellipse(1); }
  50%  { corner-shape: superellipse(0.5); }
  100% { corner-shape: superellipse(1); }
}

Specification

The superellipse() CSS function is defined in the CSS Borders and Box Decorations Module Level 4 specification. As of this writing, the spec is in Editor’s Draft status, which means the function’s behavior is stable enough to experiment with, but details may still change as the spec progresses toward Candidate Recommendation.

Browser support

Further reading