CSS shape() Function: Responsive clip-path Shapes

Path shapes without SVG clip paths

Creating non-rectangular clip paths used to mean SVG <clipPath> elements or path() with fixed pixel coordinates that break as soon as the element resizes. shape() brings path-style drawing to CSS using percentage units and responsive coordinates.

Old way 8 lines
/* path() uses absolute px — not responsive */.hero   {  clip-path: path(     "M 0 0 L 800 0 L 800 360 /* */  Q 400 420 0 360 Z" /* */  );  /* Breaks on resize */}
Modern
9 lines
.hero   {  clip-path: shape(     from 0% 0%,    line to 100% 0%,    line to 100% 80%,    curve to 0% 80% via 50% 105%,    close   );}
Limited availability 85% global usage

This feature is not Baseline because it does not work in some of the most widely-used browsers.

Not ready for production without a fallback.

135+
18.4+
135+
shape() clips with responsive % coordinates
Wavy hero
shape()
shape()
curve to 0% 75% via 50% 105% — scales with the element

Responsive units

shape() accepts percentages, calc(), and any CSS length. The shape scales with the element automatically.

No SVG required

No inline SVG, no <clipPath> element, no hidden SVG containers. The shape lives in CSS where it belongs.

Animatable

Unlike SVG clip paths, shape() supports CSS transitions and animations between compatible shapes.

Old Approach
path() or SVG
Fixed pixel values
Modern Approach
shape()
Responsive, animatable
Units
%, calc(), rem
vs px-only path()

How it works

The clip-path: path() function takes SVG path data, which uses absolute pixel coordinates. A path drawn for an 800px-wide element looks wrong at any other width. The workaround was SVG <clipPath> elements with clipPathUnits="objectBoundingBox" and 0–1 fractional coordinates. A complex setup hidden in HTML.

shape() brings path drawing commands directly into CSS with support for responsive units. from 0% 0% sets the starting point, line to 100% 0% draws a line, curve to draws a cubic Bézier, and close closes the path. Every coordinate can use percentages, vw, rem, or calc().

Support is Chrome 135+, Edge 135+, and Safari 18.4+. Firefox support is arriving in early 2026. This is an Interop 2026 focus area, so cross-browser coverage will improve throughout the year.

ESC