CSS offset-path Reference Guide

Tiger AbrodiTiger Abrodi
4 min read

Core Concept

offset-path = places any element along a curved path (like a train on tracks) offset-distance = controls position along the path (0% = start, 100% = end)

Basic Syntax

.element {
  offset-path: path("M0 0 Q100 50 200 0"); /* curved path */
  offset-distance: 0%; /* position on path */
  transition: offset-distance 1s; /* animate movement */
}

.element.active {
  offset-distance: 100%; /* move to end */
}

Key Properties

offset-path

Defines the path using SVG path syntax

offset-path: path("M50 50 Q150 0 250 50"); /* quadratic curve */
offset-path: path("M0 0 L100 0 L100 100 L0 100 Z"); /* square path */

offset-distance

Position along the path (percentage)

offset-distance: 0%; /* start of path */
offset-distance: 50%; /* middle of path */
offset-distance: 100%; /* end of path */

offset-anchor

Which part of element touches the path

offset-anchor: center; /* element center on path */
offset-anchor: top left; /* element top-left on path */
offset-anchor: 10px 10px; /* custom point */

offset-rotate

How element rotates along path

offset-rotate: auto; /* follows path direction (default) */
offset-rotate: 0deg; /* no rotation */
offset-rotate: 90deg; /* fixed rotation */

Element Type Differences

SVG Elements

/* Uses SVG coordinate system */
rect {
  offset-path: path("M20 20 Q80 20 80 80");
  offset-anchor: 0 0; /* default: top-left corner */
}
  • Coordinates: SVG viewBox units

  • Default anchor: Top-left corner (0,0)

  • Path origin: SVG coordinate system

DOM Elements (div, button, etc)

/* Uses pixel coordinates from element position */
.button {
  offset-path: path("M0 0 Q150 0 300 200");
  offset-anchor: center; /* default: center */
}
  • Coordinates: Pixels relative to element's current position

  • Default anchor: Center of element

  • Path origin: Element's top-left corner

Common Patterns

Basic Curved Animation

.element {
  offset-path: path("M0 0 Q100 -50 200 0");
  offset-distance: 0%;
  transition: offset-distance 2s ease;
}

.element:hover {
  offset-distance: 100%;
}

Circular/Loop Movement

.element {
  offset-path: path("M100 50 A50 50 0 1 1 100 51"); /* circle */
  offset-distance: 0%;
  animation: loop 3s infinite linear;
}

@keyframes loop {
  to {
    offset-distance: 100%;
  }
}

Complex Multi-segment Path

.element {
  offset-path: path("M50 100 Q150 50 250 100 Q350 150 450 100");
  offset-distance: 0%;
}

Practical Examples

Button Press Animation

.button {
  offset-path: path("M0 0 Q50 -30 100 0");
  offset-distance: 0%;
  transition: offset-distance 0.3s ease;
}

.button:active {
  offset-distance: 100%;
}

Loading Spinner

.spinner {
  offset-path: path("M50 25 A25 25 0 1 1 50 26");
  animation: spin 1s infinite linear;
}

@keyframes spin {
  to {
    offset-distance: 100%;
  }
}

CD/Disc Animation

.cd-wrapper {
  offset-path: path("M32 32C96.5 -25.5 132.865 26.0836 140 192");
  offset-distance: 0%;
  transition: all 0.5s;
}

.cd-wrapper[aria-pressed="true"] {
  offset-distance: 100%;
  width: 192px;
  height: 192px;
}

Common Path Commands

/* Line */
path('M0 0 L100 100') /* from (0,0) to (100,100) */

/* Quadratic curve */
path('M0 0 Q50 -50 100 0') /* control point at (50,-50) */

/* Cubic curve */
path('M0 0 C25 -25 75 -25 100 0') /* two control points */

/* Arc */
path('M0 0 A50 50 0 0 1 100 0') /* arc with radius 50 */

/* Complex shape */
path('M50 0 Q100 25 50 50 Q0 25 50 0') /* diamond shape */

Gotchas & Tips

Coordinate System Confusion

/* SVG element - uses SVG coordinates */
circle {
  offset-path: path("M20 20 Q80 20 80 80");
}

/* DOM element - uses pixels from current position */
.div {
  offset-path: path("M0 0 Q60 0 120 60");
}

Anchor Point Issues

/* Default anchors are different! */
/* SVG: top-left, DOM: center */

/* Fix by being explicit */
.element {
  offset-anchor: center; /* or whatever you want */
}

Path Direction Matters

/* This goes right */
path('M0 0 L100 0')

/* This goes left (backwards!) */
path('M100 0 L0 0')

Animation Performance

/* Good - animates offset-distance */
.element {
  transition: offset-distance 1s;
}

/* Avoid animating offset-path itself */
0
Subscribe to my newsletter

Read articles from Tiger Abrodi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Tiger Abrodi
Tiger Abrodi

Just a guy who loves to write code and watch anime.