Skip to main content

CSS Corner Properties: border-radius, corner-shape, and Superellipse

By LearnWebCraft Team11 min read
CSSborder-radiuscorner-shapeUI Design

Do you know that feeling when a UI looks modern, expensive, and somehow more intentional than the usual “rounded rectangle everywhere” pattern? A surprising amount of that feeling comes from corners.

I’m serious. Corners do a lot more visual work than we usually give them credit for.

The difference between a soft dashboard, a playful card system, and a sharp enterprise admin panel is often not typography, spacing, or shadows alone. It is the geometry. It is the way the surface ends. It is the corner.

Most of us learned border-radius years ago and then kind of stopped there. And fair enough, because border-radius is still incredibly useful. But modern CSS is starting to give us more expressive corner control, especially with corner-shape and the broader direction of corner geometry in CSS.

This tutorial is a proper LearnWebCraft-style walkthrough, not just a quick note. We are going to cover:

  • what corner properties actually do
  • where border-radius still wins
  • how corner-shape works in practice
  • how to think about per-corner geometry in component systems
  • how to ship it safely with progressive enhancement
  • how to use it in real design systems without creating visual chaos

This guide is written as a practical teaching tutorial so users can understand both the fundamentals and the production use cases of modern corner styling.

The Big Idea: Corners Are Part of Your Design Language

When teams talk about design systems, they usually obsess over:

  • typography scales
  • spacing tokens
  • color palettes
  • shadows
  • breakpoints

All good. All necessary.

But corner treatment is just as important because it affects how users feel the interface.

Think about it this way:

  • Large soft rounded corners often feel friendly and approachable.
  • Tight geometric corners feel more dense, technical, or serious.
  • Beveled corners can feel engineered or industrial.
  • Scooped or concave corners can feel playful and custom.
  • Squircles can make an interface feel premium and product-led.

That means corners are not random decoration. They are product language.

If your system uses tokens for spacing, then honestly, your corners deserve tokens too.

First Principle: border-radius Is Still the Foundation

Before we get excited about newer properties, let’s stay disciplined.

border-radius remains the production baseline because it is predictable, broadly supported, and already powerful enough for a lot of UI work.

.card {
  border-radius: 16px;
}

.button {
  border-radius: 9999px;
}

.avatar {
  border-radius: 50%;
}

Simple? Yes. Limited? Not nearly as much as people think.

Multi-value radius is more expressive than most teams use

You are not limited to one radius value. You can use different values per corner:

.promo-card {
  border-radius: 40px 12px 48px 18px;
}

That alone can create interfaces that feel more editorial, more branded, or more organic.

And if you want to get even more advanced, you can use the elliptical syntax:

.organic-surface {
  border-radius: 48px 16px 36px 24px / 28px 42px 18px 30px;
}

That slash syntax lets horizontal and vertical corner radii differ, which gives you asymmetrical curves that feel much less generic.

So before you reach for experimental shape properties, make sure you are already getting full value from border-radius. A lot of teams are not.

Where border-radius Starts to Feel Limiting

Eventually, though, you hit a wall.

Rounded corners are great, but they are all variations of the same basic idea: outward curvature. What if you want something more geometric or more branded?

For example:

  • a diagonal bevel on a card corner
  • a concave inward “scoop” on a feature block
  • a notched action chip
  • a squircle-style control that feels more product-designed than simply rounded

That is where corner-shape becomes interesting.

Enter corner-shape

The corner-shape property defines the geometric shape of corners, but it works together with border-radius. That second part matters a lot.

If you forget to give the element a non-zero radius, the shape change will not really have visible room to happen.

Basic example:

.panel {
  border-radius: 28px;
  corner-shape: scoop;
}

That tells the browser: “Take the corner area established by border-radius, then draw it with a scooped geometry instead of the default rounded one.”

This is the mental model I recommend:

  • border-radius defines how much corner space exists
  • corner-shape defines what geometry happens inside that space

Once that clicks, the property starts making a lot more sense.

The Values You Should Actually Understand

The key value set includes:

  • round
  • squircle
  • square
  • bevel
  • scoop
  • notch
  • superellipse(k)

Let’s make those practical.

round

This is the familiar rounded-corner behavior. Think “normal modern UI.”

.card {
  border-radius: 24px;
  corner-shape: round;
}

squircle

This lands between square and circle. It often feels more refined than standard rounded rectangles.

.app-icon {
  border-radius: 28px;
  corner-shape: squircle;
}

If your interface is heavily product-driven, this can create a stronger visual signature than plain rounded corners.

bevel

This cuts the corner diagonally. It feels more technical and angular.

.badge {
  border-radius: 20px;
  corner-shape: bevel;
}

scoop

This creates a concave corner. It can look surprisingly fresh when used carefully.

.feature-card {
  border-radius: 32px;
  corner-shape: scoop;
}

notch

This creates a sharper inward cut and can feel very stylized.

.ticket {
  border-radius: 24px;
  corner-shape: notch;
}

superellipse(k)

This is the most advanced option because it lets you choose custom curvature mathematically.

You do not need to become a geometry expert to use it, but you should understand the rough direction:

  • positive values push toward outward curvature
  • negative values move toward inward or concave behavior
.brand-surface {
  border-radius: 28px;
  corner-shape: superellipse(2.5);
}

This is powerful, but use it with restraint. Design systems get unstable very fast when every component invents its own corner math.

One to Four Values: Per-Corner Control

Like many CSS shorthands, corner-shape can accept one to four values.

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

That maps clockwise:

  1. top-left
  2. top-right
  3. bottom-right
  4. bottom-left

This is where the property becomes genuinely expressive. You can create cards that feel directional, decorative, or uniquely branded without building SVG masks or weird pseudo-element hacks.

But a warning: just because you can make every corner different does not mean you should.

In production UI, mixed-corner styling works best when there is a clear reason:

  • a callout that needs one emphasized edge
  • a feature block that visually points toward adjacent content
  • a branded hero card with intentional asymmetry

Random shape mixing usually just looks noisy.

Physical and Logical Corner Properties

This distinction is especially useful in systems that care about more robust layout direction handling.

There are physical properties such as:

  • corner-top-left-shape
  • corner-top-right-shape
  • corner-bottom-right-shape
  • corner-bottom-left-shape

And there are logical equivalents for writing-mode-aware layouts.

That matters if your project cares about internationalization, RTL layouts, or more robust logical CSS usage.

Example with physical corner targeting:

.callout {
  border-radius: 32px;
  corner-top-left-shape: scoop;
  corner-top-right-shape: round;
  corner-bottom-right-shape: bevel;
  corner-bottom-left-shape: notch;
}

If your system already prefers logical properties in spacing and layout, then using logical corner properties is the cleaner long-term choice.

A Better Production Strategy: Progressive Enhancement

This is the part I want users to really learn.

Do not treat corner-shape like a universal baseline property yet. Treat it like an enhancement layer.

Your safest pattern is:

  1. define a good border-radius fallback
  2. add corner-shape only inside @supports
.surface {
  border-radius: 24px;
}

@supports (corner-shape: scoop) {
  .surface {
    corner-shape: scoop;
  }
}

This gives you graceful behavior immediately:

  • unsupported browsers still render a good UI
  • supported browsers get richer geometry
  • your design system does not depend on unstable support assumptions

That is the right engineering bar.

Advanced Tutorial: Building a Corner Token System

Here is where we move from “cool property demo” into real frontend architecture.

If you are building a reusable system, do not hardcode corner behavior all over the codebase. Tokenize it.

I recommend separating two concerns:

  1. radius amount
  2. shape style
:root {
  --radius-sm: 10px;
  --radius-md: 18px;
  --radius-lg: 28px;

  --shape-default: round;
  --shape-brand: squircle;
  --shape-accent: scoop;
}

.card {
  border-radius: var(--radius-md);
}

@supports (corner-shape: round) {
  .card {
    corner-shape: var(--shape-default);
  }

  .card--brand {
    corner-shape: var(--shape-brand);
  }

  .card--accent {
    corner-shape: var(--shape-accent);
  }
}

Why split radius and shape?

Because they solve different problems:

  • radius controls density and softness
  • shape controls geometry and brand character

If you combine them into one token concept, your system becomes harder to scale.

Advanced Tutorial: Using Corner Shapes in Component Hierarchy

Let’s say you have a dashboard with cards, buttons, drawers, and modals. You do not want everything to use the same corner treatment.

That produces a flat, repetitive UI.

A better pattern is to assign corner roles by component purpose:

:root {
  --radius-card: 20px;
  --radius-action: 9999px;
  --radius-modal: 28px;
}

.card {
  border-radius: var(--radius-card);
}

.button {
  border-radius: var(--radius-action);
}

.modal {
  border-radius: var(--radius-modal);
}

@supports (corner-shape: round) {
  .card {
    corner-shape: round;
  }

  .button--primary {
    corner-shape: squircle;
  }

  .promo-card {
    corner-shape: scoop;
  }
}

This creates hierarchy through geometry:

  • neutral surfaces stay calm
  • primary actions feel more intentional
  • promotional content gets a more memorable edge treatment

That is much better than applying the same fancy corner everywhere.

Advanced Tutorial: Safe Hover and Motion Patterns

The source also notes animation and transitions. Yes, you can transition corner changes, but you should be careful.

This is not the property to turn into constant decorative motion on every card in the interface.

A better use case is restrained interactive emphasis:

.interactive-tile {
  border-radius: 24px;
  transition:
    transform 180ms ease,
    box-shadow 180ms ease,
    corner-shape 180ms ease;
}

.interactive-tile:hover {
  transform: translateY(-2px);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.12);
}

@supports (corner-shape: bevel) {
  .interactive-tile:hover {
    corner-shape: bevel;
  }
}

That feels intentional. It supports interaction. It does not scream for attention.

Advanced Tutorial: Combining border-radius and corner-shape Intelligently

This is where people can make a mess if they do not understand the relationship.

Bad pattern:

  • giant random radii
  • aggressive mixed shapes
  • heavy shadows
  • multiple animated corners

That usually creates visual noise and weird clipping.

Better pattern:

  • start with one radius scale
  • pick one shape family for the product
  • reserve unusual shapes for emphasis areas
  • test with shadows, borders, and background contrast together

Example:

.feature-panel {
  border-radius: 24px;
  background: white;
  border: 1px solid rgba(15, 23, 42, 0.08);
  box-shadow: 0 18px 40px rgba(15, 23, 42, 0.08);
}

@supports (corner-shape: squircle) {
  .feature-panel {
    corner-shape: squircle;
  }
}

That is elegant because everything else stays restrained.

Key Implementation Notes

Before shipping this pattern in production, keep these practical details in mind:

  • corner-shape works with border-radius, not as a replacement for corner sizing.
  • The property can accept one, two, three, or four values depending on how much per-corner control you need.
  • Physical and logical directional variants both matter in robust layouts.
  • Mixed corner combinations can create visual complexity quickly, so constrain them with a clear design rule.
  • Progressive enhancement remains the safest production strategy.

What to Test Before You Ship This

If you are serious about using advanced corners in production, test these things explicitly:

  • fallback appearance when corner-shape is unsupported
  • whether shadows follow the shape cleanly
  • whether borders look crisp at different DPI scales
  • how the component behaves in light and dark themes
  • how hover and focus states change the perceived geometry
  • whether very large radii collide visually on smaller components
  • whether directional corners still make sense in RTL or logical layout contexts

This is not overkill. Shape language affects perceived quality very quickly.

A Good Mental Model for Teams

If I had to reduce the whole tutorial to one production rule, it would be this:

Use border-radius for reliability. Use corner-shape for identity.

That gives you a clean separation of concerns:

  • border-radius keeps the UI robust everywhere
  • corner-shape adds brand character where supported

That is the right balance between design ambition and engineering discipline.

Final Take

Modern corner styling is one of those CSS topics that looks cosmetic at first and then becomes strategic once you really understand it.

If your users are learning CSS, they should absolutely master border-radius first. But if they want to build interfaces that feel more custom, more premium, and less interchangeable, then learning corner geometry is a very smart next step.

Start simple. Tokenize your radii. Add corner-shape behind @supports. Use unusual corner treatments sparingly. And always test the whole component, not just the corner in isolation.

That is how you turn an experimental-looking property into a practical frontend skill.

Related Articles