Motion Path
The CSS offset-path property that animates elements traveling along a custom SVG path or geometric shape — enabling curved trajectories, looping routes, and complex motion choreography.
Plain English
Every CSS animation you have ever written moves in a straight line — translateX slides left to right, translateY moves up and down. Motion path breaks that constraint. You define a path — a bezier curve, an arc, a figure-eight, a complex SVG shape — and the element travels along it automatically, rotating to follow the curve as it goes. This is how you make an icon sweep around a circle, a notification fly in on a curved trajectory, a loading dot bounce along an arc, or a character walk along a custom route. The results look hand-crafted because the motion follows a physical curve rather than the rigid XY grid of normal transforms. It is the CSS equivalent of "follow path" in animation software like After Effects.
Technical
Key properties: `offset-path` (the path), `offset-distance` (how far along the path, 0%–100%), `offset-rotate` (how the element orients — `auto` follows the tangent). Animate `offset-distance` from 0% to 100% via `@keyframes`. Path sources: `offset-path: path("M 0 0 C 100 -100 200 100 300 0")` (SVG path data inline), `offset-path: circle(80px)`, `offset-path: ellipse(120px 60px)`, `offset-path: polygon(...)`, or `offset-path: url(#svgPathId)` (references an `<svg> <path id="svgPathId">` in the DOM). For `url()`, the SVG must be inline in the HTML — external SVG files do not work. `offset-anchor` controls which point of the element sits on the path (default: `auto`, the element’s center or `transform-origin`). `offset-rotate: auto` makes the element face the direction of travel (great for arrows, cars, birds). `offset-rotate: 0deg` keeps the element upright regardless of path direction. Animation: `@keyframes travel { from { offset-distance: 0%; } to { offset-distance: 100%; } }`. Apply `animation: travel 3s linear infinite`. Combine with `offset-rotate: auto 45deg` to add a fixed bias to the auto-rotation. Browser support: Chrome 79+, Firefox 72+, Safari 16+ (with `-webkit-` prefix for older Safari). Fallback: provide a straight-line translateX/translateY animation for non-supporting browsers using `@supports not (offset-path: path("M0 0"))`. Performance: `offset-distance` is GPU-composited alongside `transform` and `opacity` — does not trigger layout or paint.
Live Demo
Motion Path
A dot travels along a cubic bezier curve. In CSS, use offset-path: path(…) with offset-distance animated from 0% to 100%.
.dot {
offset-path: path("M 30,80 C 120,10 200,150 290,50");
offset-distance: 0%;
animation: along-path 2.2s ease-in-out forwards;
}
@keyframes along-path {
to { offset-distance: 100%; }
}
Motion paths make UI elements follow curves — great for loading indicators or guided tours.
Usage
✓ Good usage
A brand-moment loading animation where the company's logo mark travels along a custom bezier path (the shape of the brand letter) at 2s linear infinite — the element rotates to follow the curve's tangent with `offset-rotate: auto`, making the motion feel natural and deliberate.
✗ Bad usage
Using motion-path for a simple slide-in notification that could be done with `translateX` — the added complexity of defining a path buys nothing when the motion is already a straight line.
Recommended values
- offset-rotate: auto (element faces direction of travel)
- offset-rotate: 0deg (element stays upright)
- Use path() for complex curves, circle()/ellipse() for geometric loops
- Animation timing: linear for constant-speed loops, ease-in-out for dramatic entrances
- Combine with opacity: 0→1 and scale for entrance choreography
- @supports not (offset-path: ...) fallback to translateX/Y
Common mistakes
- Using `offset-path: url(#id)` with an external SVG file — only inline `<svg>` in the HTML document can be referenced; external files are not loaded.
- Forgetting `offset-rotate: auto` and wondering why the element does not follow the curve direction — by default, the element maintains its original orientation.
- Defining path coordinates relative to the wrong origin — `path()` coordinates are relative to the element's position; complex paths often need `position: absolute` on the element to behave predictably.
- Omitting a `@supports` fallback — motion path has non-trivial browser support gaps and silently does nothing on older Safari.
AI Prompt Example
Copy this into Claude, Cursor, Bolt, or v0.
Animate the notification icon along an arc. Use `offset-path: path("M 0 0 Q 60 -80 120 0")` to define a parabolic arc. Animate `offset-distance` from 0% to 100% over 0.6s `cubic-bezier(0.34, 1.56, 0.64, 1)` (spring-like overshoot). Set `offset-rotate: 0deg` to keep the icon upright. Fade in with `opacity: 0→1` over the first 0.2s. Wrap in `@supports (offset-path: path("M0 0"))` with a translateY(-40px) fallback for unsupported browsers.