DEV Community

Mikhail Mogilnikov
Mikhail Mogilnikov

Posted on

How I Brought CSS corner-shape to Safari and Firefox

How I Brought CSS corner-shape to Safari and Firefox

The new CSS corner-shape property is one of the most exciting additions to modern CSS.

It allows developers to create squircles, superellipses, scoops, notches, and other corner geometries using pure CSS:

.card {
  corner-shape: squircle;
  border-radius: 48px;
}
Enter fullscreen mode Exit fullscreen mode

Unfortunately, there's a catch.

Today, corner-shape only works in Chromium-based browsers. Safari and Firefox ignore the property entirely and fall back to ordinary rounded corners.

As a result, the same stylesheet can produce completely different geometry depending on the browser.

Why This Matters

For years, designers have relied on SVG masks, clip-paths, custom canvas renderers, and various smoothing tricks to achieve shapes that go beyond traditional rounded rectangles.

The arrival of corner-shape finally gives us a standard CSS solution.

Instead of describing geometry through SVGs or custom rendering code, we can express it directly in CSS:

.card {
  corner-shape: squircle;
  border-radius: 48px;
}
Enter fullscreen mode Exit fullscreen mode

The problem is browser support.

A feature that's only available in one browser is difficult to adopt in production.

Existing Approaches

Before building a polyfill, I explored several alternatives:

  • SVG masks
  • clip-path
  • canvas rendering
  • custom squircle implementations

Most of them work well for simple demos.

However, things become much more complicated when you start dealing with real UI components.

Questions quickly appear:

  • What about borders?
  • What about outlines?
  • What about shadows?
  • What about SSR?
  • What about transitions?
  • What about responsive layouts?

More importantly, none of these approaches actually implement the CSS specification.

They simply generate a shape that looks similar.

The Goal

I wanted developers to be able to write standard CSS and get consistent results everywhere.

.card {
  corner-shape: squircle;
  border-radius: 48px;
}
Enter fullscreen mode Exit fullscreen mode

The desired behavior is straightforward:

  • Chromium uses native rendering.
  • Safari and Firefox use a fallback.
  • The geometry remains consistent.

Developers shouldn't need separate implementations for different browsers.

Matching Native Geometry

This turned out to be the hardest part of the project.

Generating a squircle is relatively easy.

Generating a squircle that visually matches Chromium's implementation is much harder.

Even small geometric differences become obvious when shapes are compared side by side.

A significant portion of the work went into reproducing the geometry defined by the CSS Borders Level 4 specification and comparing the output against native browser rendering.

The goal wasn't to create a shape that looked close enough.

The goal was to create a fallback that felt indistinguishable from native rendering.

Beyond Geometry

A production-ready solution requires more than shape generation.

The implementation also needed to support:

  • borders
  • outlines
  • shadows
  • background images
  • gradients
  • responsive layouts
  • width and height transitions
  • server-side rendering

Many of these features introduce additional geometry and rendering challenges that don't appear in simple shape demos.

Native-First Architecture

One of the design goals was to avoid replacing native browser behavior.

When corner-shape is available, the browser should remain responsible for rendering.

Hyperellipse only activates in browsers that don't support the property.

The result is a native-first approach:

  • Native rendering in Chromium
  • Fallback rendering in Safari and Firefox

Developers continue using the same CSS API everywhere.

SSR Support

Another challenge was SSR.

Without careful handling, shapes can visibly change during hydration when JavaScript loads.

To avoid that, Hyperellipse includes an SSR-friendly strategy that minimizes visual differences before the runtime becomes active.

This allows components to remain visually stable from the first paint.

The Result

The final result is Hyperellipse, an open-source CSS corner-shape polyfill.

It brings:

  • squircles
  • superellipses
  • scoops
  • notches
  • bevels
  • squares

to browsers without native support while preserving native rendering where support already exists.

Example

.card {
  --corner-shape: squircle;
  border-radius: 48px;
}
Enter fullscreen mode Exit fullscreen mode
import { registerHyperellipse } from "hyperellipse";

registerHyperellipse();
Enter fullscreen mode Exit fullscreen mode

Links

Documentation:

hyperellipse

CSS polyfill for squircles, superellipses, scoops, notches in any browser. Supports every frontend framework. SSR-friendly. Open-source.

favicon hyperellipse.vercel.app

GitHub:

GitHub logo mikhailmogilnikov / hyperellipse

CSS corner-shape polyfill — squircles, superellipses, scoops & notches

hyperellipse

hyperellipse

Docs: hyperellipse.vercel.app

npm version CI skills.sh License: MIT

A transparent polyfill for CSS corner-shape — squircles, superellipses, scoops, notches, and per-corner mixes.

Native rendering where the browser already supports corner-shape. A spec-accurate JS fallback everywhere else (Safari, Firefox).

.card {
  --corner-shape: squircle;
  border-radius: calc(24px * var(--corner-scale, 1));
  background: #4f46e5;
}
Enter fullscreen mode Exit fullscreen mode
import { registerHyperellipse } from "hyperellipse";

registerHyperellipse();
Enter fullscreen mode Exit fullscreen mode

Features

  • Progressive — supporting browsers get a tiny zero-specificity CSS bridge; no observers, no layout work in JS
  • Spec-aligned geometry — superellipse math from CSS Borders 4, so Chrome and the fallback match
  • Real-world CSS — backgrounds, gradients, borders, box-shadow, outline + outline-offset
  • SSR-friendly — optional --corner-scale snippet removes the flash of overly round corners before hydration
  • Tiny API — one registerHyperellipse() call; idempotent and SSR-safe

Installation

npm install hyperellipse
# bun add hyperellipse
# pnpm add hyperellipse
Enter fullscreen mode Exit fullscreen mode

I'm curious to hear feedback from anyone experimenting with corner-shape, browser rendering, or modern CSS geometry.

Top comments (0)