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 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.
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: bevelcorner-shape: scoopcorner-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.
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.
<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%; }
}
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.