CSS border-shape reshapes a box's actual geometry — backgrounds, borders, focus outlines, and shadows all follow the new edge. clip-path just hides what falls outside.
Inspired by Una Kravets's writeup.
border-shape only works in Chrome Canary 146+ with experimental web platform features turned on (chrome://flags/#enable-experimental-web-platform-features). Everywhere else this page falls back to clip-path, so you'll see the silhouettes but not the box-shadow trick that makes border-shape special.
Same polygon, same hard shadow. Watch what happens to the shadow on the angled edge.
Clips everything — including the shadow that should fall outside the cut edge.
.slanted-clip {
clip-path: polygon(0 0, 100% 0, 85% 100%, 0 100%);
}Reshapes the actual box, so the shadow follows the angled edge.
.slanted-shape {
border-shape: polygon(0 0, 100% 0, 85% 100%, 0 100%);
}Each demo uses border-shape with a clip-path fallback so it renders something everywhere. In Chrome Canary with the flag on, the shadow rides the contour on every one.
One-sided arrow for a "next step" tab.
border-shape: shape(
from top left,
hline to calc(100% - var(--arrow)),
line to right center,
line to calc(100% - var(--arrow)) bottom,
hline to left,
close
);Two-sided arrow that reads as a breadcrumb segment.
border-shape: shape(
from left center,
line to var(--arrow) top,
hline to calc(100% - var(--arrow)),
line to right center,
line to calc(100% - var(--arrow)) bottom,
hline to var(--arrow),
close
);Sci-fi panel vibe. Eight-point polygon for the cut corners.
border-shape: polygon(
var(--cut) 0, calc(100% - var(--cut)) 0,
100% var(--cut), 100% calc(100% - var(--cut)),
calc(100% - var(--cut)) 100%, var(--cut) 100%,
0 calc(100% - var(--cut)), 0 var(--cut)
);Tail on the lower left. The shadow extends down past the tail.
border-shape: shape(
from top left,
hline to right,
vline to calc(100% - var(--tail)),
line to 40% calc(100% - var(--tail)),
line to 28% bottom,
line to 26% calc(100% - var(--tail)),
hline to left,
close
);Six-point polygon with aspect-ratio for clean proportions.
border-shape: polygon(
25% 0, 75% 0,
100% 50%,
75% 100%, 25% 100%,
0 50%
);Ten-point polygon. Hard to draw cleanly with anything but math.
border-shape: polygon(
50% 0%, 61% 35%, 98% 35%,
68% 57%, 79% 91%, 50% 70%,
21% 91%, 32% 57%, 2% 35%,
39% 35%
);Eight-sided regular polygon. The fill still occupies the new geometry.
border-shape: polygon(
30% 0, 70% 0,
100% 30%, 100% 70%,
70% 100%, 30% 100%,
0 70%, 0 30%
);Pointed ends like a flag or award ribbon.
border-shape: shape(
from top left,
hline to right,
line to calc(100% - var(--notch)) center,
line to right bottom,
hline to left,
line to var(--notch) center,
close
);Mimics a folded paper corner. The triangle is a pseudo-element on top.
border-shape: shape(
from top left,
hline to calc(100% - var(--fold)),
line to right var(--fold),
vline to bottom,
hline to left,
close
);Curves with the curve to … with command. Good for section breaks.
border-shape: shape(
from top left,
hline to right,
vline to 75%,
curve to 70% 75% with 92% 95% / 78% 95%,
curve to 40% 75% with 62% 55% / 48% 55%,
curve to 10% 75% with 32% 95% / 18% 95%,
curve to 0 95% with 5% 55%,
close
);The border-shape property accepts the same kinds of values as clip-path:
| value | what it does |
|---|---|
circle(r at x y) | Reshape into a circle. |
ellipse(rx ry at x y) | Reshape into an ellipse. |
inset(top right bottom left round r) | Inset rectangle, optionally rounded. |
polygon(x y, x y, …) | Straight-edged polygon from a list of points. |
path("M … Z") | SVG-style path data string. |
shape(from x y, line to x y, …) | CSS-native path syntax with named keywords like top, right, center. |
The shape() function is the easier one to write by hand. Inside it:
from <point> | Starting position. |
line to <point> | Straight line. |
hline to <x> | Horizontal line — only x changes. |
vline to <y> | Vertical line — only y changes. |
curve to <point> with <cp1> / <cp2> | Bezier curve. One control point = quadratic, two = cubic. |
arc to <point> of <radius> | Circular arc. |
close | Close the path back to the start. |
Coordinates accept percentages, lengths, calc(), and the keywords top right bottom left center. So line to right center is a real, readable point.
For years the standard trick for non-rectangular UI — angled tabs, ribbons, speech bubbles — has been clip-path. It works for the silhouette but it's a mask: anything that should bleed past the new edge gets cut. Drop shadows look wrong. Outlines on focus stop at the shape's bounding box, not its edge. Border images don't follow the curve.
border-shape fixes all of that by treating the new geometry as the actual box. The browser knows where the edge of the element really is, so everything that decorates an edge — shadows, outlines, borders — follows it.
This is still early. Today it's a Chrome Canary preview behind a flag, and the spec ships as part of CSS Borders and Box Decorations Module Level 4. But it's a meaningful change. Padding-must-be-wide-enough warnings and a few quirky bugs aside, this is the missing piece for shaped UI on the web.