SVG path follow
Make a CSS element follow an arbitrary SVG path exactly, using offset-path with a path() definition extracted from SVG — copy the d attribute straight into CSS.
Quick implementation
/* Use the same path data as your SVG's `d` attribute */
.follower {
offset-path: path('M 30,100 Q 80,20 140,100 Q 200,180 260,100 Q 320,20 370,100');
offset-distance: 0%;
offset-rotate: auto;
animation: follow-path 3s linear infinite;
}
@keyframes follow-path {
to { offset-distance: 100%; }
}
@media (prefers-reduced-motion: reduce) {
.follower { animation: none; }
}
Prompt this to your LLM
Includes role, constraints, two framework variants, and edge cases to handle.
You are a senior frontend engineer building CSS motion path animations.
Goal: Make a CSS element follow an arbitrary SVG path by extracting the
SVG path's `d` attribute and using it verbatim in CSS offset-path — no
JavaScript, no coordinate conversion.
Technical constraints:
- Render the guide path as a visible SVG <path> element in the background,
marked aria-hidden="true".
- Use the identical path string in offset-path: path('...') on the CSS
element — both use the same coordinate space.
- Animate offset-distance from 0% to 100% with @keyframes.
- Add offset-rotate: auto so the follower faces its direction of travel.
- Position the container as position: relative; the follower as
position: absolute; top: 0; left: 0 — this aligns the CSS coordinate
space with the SVG viewBox coordinate space.
- Use oklch() for all color values — no hex or rgba.
- Wrap the animation in @media (prefers-reduced-motion: reduce) and stop it.
Framework variant (pick one):
A) Vanilla CSS — a .follower class that accepts any SVG path string.
B) React component — accepts pathD (string, copied from SVG editor),
duration (number), and color (string) props; renders the SVG guide
and animated follower together.
Edge cases to handle:
- The SVG viewBox and the CSS container must share the same coordinate
space — set the SVG width/height to 100% of the container and ensure
preserveAspectRatio matches your layout intent.
- Paths with many segments (e.g. complex illustrations) still work but
may increase GPU memory usage — profile with DevTools Layers panel.
- If the path is not closed (no Z command), the follower jumps at 100% —
consider animating to 99% or using iteration-count: 1 for one-shot.
Return CSS only (or a React component if variant B).
The key insight: identical syntax between SVG and CSS
The key insight is that the path() string in offset-path uses identical syntax to the SVG d attribute. This means you can draw a path in your SVG editor (Figma, Inkscape, Illustrator), copy the d attribute value, and paste it directly into CSS. No coordinate conversion, no library, no JavaScript — the same string drives both the visible guide and the animation.
This makes it practical to animate elements along complex, hand-crafted paths. Design the path visually in your vector tool, export the SVG, grab the d value, and drop it into your stylesheet.
How the coordinate spaces align
Render the SVG background path as a visible guide using a <svg> element with a <path> element. The animated CSS element uses an identical path() string in offset-path. The Q quadratic bezier commands in this example produce smooth curves with a single control point each — a simpler alternative to cubic bezier when you only need one handle per segment.
For the CSS and SVG coordinate spaces to align, the SVG must be positioned to cover the same area as the CSS container. Set the SVG to position: absolute; inset: 0; width: 100%; height: 100% and match the viewBox to the coordinate values used in the path string. The animated element sits at top: 0; left: 0 inside the same container, so CSS interprets the path coordinates relative to that origin — matching the SVG viewBox exactly.
offset-rotate: auto reads the tangent vector at each offset-distance value and rotates the element accordingly, giving a natural "following the road" feel to the motion.
Accessibility and performance
Keep the decorative SVG guide path aria-hidden="true" so screen readers skip it. The CSS animation is composited on the GPU, so it does not block the main thread. For paths with many segments, profile paint time in the browser's Layers panel — very long paths with many control points can increase GPU memory usage as the browser pre-computes the path geometry.
Wrap the animation in @media (prefers-reduced-motion: reduce) and stop it. Setting offset-distance: 50% in the reduced-motion block parks the follower at the midpoint of the path, keeping it visible without any motion.