offset-path: border-box does not follow corner-shape

#525581076 Filed 2026-06-19 New · P3 / S3 Blink CSS motion path

Problem

An element animated along offset-path: border-box (or padding-box / content-box) should trace the actual contour of the box, including any corner-shape modification (bevel, scoop, notch, ...). In Chrome, the motion path is built from border-radius alone, so the dot always follows the rounded corner arc -- even when the visible corner is beveled or notched.

Expected vs actual

Expected the dot follows the visible border contour, e.g. the straight diagonal edge of a beveled corner.

Actual the dot swings through a circular arc as if corner-shape were round, drifting off the visible shape at every corner.

Live demo

Each 160×160 box below has border-radius: 60px plus the labelled corner-shape, and a red dot animating along offset-path: border-box. Only in the round control should the dot follow circular arcs at the corners. In unfixed Chrome the dot traces rounded arcs in all four boxes, visibly leaving the bevel / scoop / notch outlines.

corner-shape: round (control)

corner-shape: bevel

corner-shape: scoop

corner-shape: notch

Note: corner-shape requires Chrome 139+. Browsers without corner-shape support render all boxes as circles, so all four demos look identical there.

Degenerate radii (the original codepen)

The reporter's codepen uses border-radius: 9999px on a 16:9 box, which fully constrains the radii. For concave corner shapes (notch, scoop) the resulting contour contains zero-area slivers along the horizontal midline: they paint as nothing (notch) or as tiny tips (scoop), but they are part of the border contour, so a dot on the fixed motion path briefly travels out to the left/right edge and back. The path still matches the painted contour geometry exactly. The demos above use border-radius: 60px to stay clear of that degenerate case.

Direction reversals on the codepen come from its animation: distance 8s infinite alternate -- the dot is supposed to reverse every cycle.

Reduced test case

<div class="container">   <!-- border-radius: 80px; corner-shape: bevel -->
  <div class="dot"></div> <!-- offset-path: border-box; animated offset-distance -->
</div>

.container {
  width: 160px; height: 160px;
  border-radius: 80px;
  corner-shape: bevel;     /* visible shape: a diamond */
}
.dot {
  offset-path: border-box; /* BUG: traces a circle, not the diamond */
  animation: trace 6s linear infinite;
}
@keyframes trace {
  from { offset-distance: 0%; }
  to   { offset-distance: 100%; }
}

Root cause

ComputedStyle::ApplyMotionPathTransform() (third_party/blink/renderer/core/style/computed_style.cc) builds the coord-box offset path as a BasicShapeInset using only the containing block's border-radius. The corner-shape (superellipse) properties are never consulted, while painting uses ContouredBorderGeometry and does honor them.

Fix: build the motion path from ContouredBorderGeometry::ContouredBorder(), which produces the identical rounded-rect path when the curvature is round and the contoured (bevel / scoop / notch / squircle) path otherwise.

Links

Chromium issue 525581076

Original reporter codepen

CSS Borders 4: corner-shape

Motion Path: offset-path coord-box