CSS offset-path Property

Defines a mathematical path for an element to follow, allowing for complex motion that isn't restricted to straight lines.

selector { offset-path: path("M 0 0 L 100 100"); }
none The element does not follow any motion path.
<path()> Defines a track using SVG path data syntax for complex movement.
<ray()> Defines a line starting from the element position following a specific angle and size.
<basic-shape> Uses standard shapes like circle(), ellipse(), inset(), or polygon() as the path.
<url> References the ID of an external or internal SVG path element.
margin-box Uses the edge of the margin box as the motion path.
border-box Uses the edge of the border box as the motion path.
padding-box Uses the edge of the padding box as the motion path.
content-box Uses the edge of the content box as the motion path.

Code Examples

A basic example showing a red ball following a curved Bezier path defined by SVG path data within a container.

<style>
.track {
  width: 300px;
  height: 300px;
  border: 2px dashed #cccccc;
  position: relative;
}
.ball {
  width: 20px;
  height: 20px;
  background: #ff0000;
  border-radius: 50%;
  offset-path: path("M 20 250 C 20 20, 280 20, 280 250");
  animation: travel 4s infinite linear;
}
@keyframes travel {
  from { offset-distance: 0%; }
  to { offset-distance: 100%; }
}
</style>
<div class="track">
  <div class="ball"></div>
</div>

An advanced example using a circular motion path and the Web Animations API to drive an element in a continuous orbit with custom rotation.

<style>
#ufo {
  width: 50px;
  height: 30px;
  background: #00ff00;
  position: absolute;
  offset-path: circle(100px at 150px 150px);
  offset-rotate: auto 90deg;
}
</style>
<div style="width: 300px; height: 300px; background: #222222; position: relative;">
  <div id="ufo"></div>
</div>
<script>
const ufo = document.getElementById("ufo");
ufo.animate([
  { offsetDistance: "0%" },
  { offsetDistance: "100%" }
], {
  duration: 3000,
  iterations: Infinity,
  easing: "linear"
});
</script>

Pro Tip

You can use the ray() function for quick, directional movement without defining complex paths. If you want an object to orbit a center point, a simple circle() value is much easier to manage and update than a complex path calculation. Also, keep in mind you can change the path itself inside an animation to create morphing movement routes.

Deep Dive

Think of offset-path as a physical slot car track. By itself, it doesn't move the element; it only provides the layout or route. You use the offset-distance property to actually drive the element along that track. This property accepts SVG path data, basic shapes, or even references to SVG elements in the DOM. It works in tandem with offset-rotate, which determines if the element turns to face the direction it is moving or stays fixed. It effectively replaces the need for complex, nested CSS transforms or heavy JavaScript math to achieve circular or irregular movement patterns.

Best Practices

Use the path() function when you need precision, as it mirrors the standard SVG syntax developers already know. Always combine this property with offset-distance in your keyframe animations to create smooth motion. For cleaner code, if your path is a simple geometric shape like a circle or ellipse, use the basic-shape functions rather than writing out the full SVG path string. Ensure your element has a clear transform-origin if the rotation isn't behaving as expected during the travel.

Common Pitfalls

A common mistake is setting the offset-path and expecting the element to move immediately. Without an accompanying offset-distance animation or value, the element will just sit at the 0% mark of the path. Also, remember that the element's center is typically what is pinned to the path; if your element looks offset, check your margins and positioning. Be aware that coordinate systems in CSS might differ slightly from the original SVG coordinate system if the path is not normalized.

Accessibility

Animations along a path can be highly distracting or cause nausea for users with vestibular disorders. Always wrap your motion-path animations in a prefers-reduced-motion media query. This allows you to either slow the animation down significantly or remove the motion entirely for users who have requested less movement in their operating system settings.

Dev Data Table: offset-path property

default none
animatable yes
inherited no
experimental no
year_intro 2015
year_standard 2023
js_syntax_1 element.style.offsetPath = "path('M 0 0 L 100 100')";
js_syntax_2 element.style.setProperty("offset-path", "circle(50% at 50% 50%)");
js_note When manipulating this property in JavaScript, ensure the path data string is correctly escaped or use single quotes inside the path function.
browsers { "Chrome": 55, "Edge": 79, "Firefox": 72, "Safari": 16, "Opera": 42, "Chrome Android": 55, "Safari on iOS": 16, "Samsung Internet": 6, "Opera Mobile": 42 }
results render here...