offset-rotate and Auto-Orientation Along a Path

Part of Motion Path & Individual Transforms in Core CSS Animation Fundamentals.

The problem

A delivery-tracking illustration animates a small van along a winding route. With offset-rotate: auto the van turns with the road — but it drives sideways, because the artwork was drawn facing up. On a sharp corner it spins around instantly. On the return leg it drives in reverse. And the label attached to it, “Out for delivery”, is upside-down for half the journey.

Every one of these is a question about which angle the browser applies at each point on the path, and every one has a one-line answer once that rule is clear.

Root cause analysis: the tangent and the element’s x-axis

When an element moves along an offset path, offset-rotate decides its rotation at every point.

With auto, the element is rotated so that its positive x-axis — pointing right in its own coordinate system — lines up with the direction of the path at that point, the tangent. Artwork that faces right follows the road correctly. Artwork that faces up is off by 90 degrees.

auto <angle> adds a fixed angle to the tangent. auto -90deg corrects artwork drawn facing up; auto 180deg corrects artwork drawn facing left.

reverse is auto 180deg: the element faces opposite to the direction of travel.

A plain <angle>, such as 0deg, ignores the path’s direction entirely and keeps a constant rotation. That is the right value for anything with text.

The sudden spin comes from the path, not the property. At a sharp corner the tangent changes direction instantly, so auto rotation changes instantly too. At a cusp — where the path doubles back — the tangent reverses and the element flips 180 degrees in one frame. The fix belongs in the path data: rounded corners give the tangent a curve to turn through.

Two ways to carry a label along a routeKeep orientation and readability on separate elements.Two ways to carry a label along a routeLabel inside the rotating vehicleoffset-rotate: auto on the wrapperText turns with every bendUpside-down on westbound legsUnreadable half the timeTwo elements on the same pathVehicle: offset-rotate: auto -90degLabel: offset-rotate: 0deg, same distanceLabel rides along, always uprightReadable throughout
Keep orientation and readability on separate elements.

Step-by-step resolution

Fixing the vanOrientation, corners, and the label — in that order.Fixing the van1Check which way the artwork faces in its own file.Up, right, left or down2Set offset-rotate: auto with the correcting angle: up needs -90deg, left needs 180deg.The van faces the road3Replace sharp corners in the path with short arcs or curves.Turning happens over several frames4Move the label to its own element on the same path with offset-rotate: 0deg.Text stays upright5Animate both elements' offset-distance with identical timing.They move together6Under reduced motion, show the van at its destination facing a fixed direction.
Orientation, corners, and the label — in that order.

Production code pattern

.route {
  position: relative;
  aspect-ratio: 480 / 220;
  --route: path("M 20 180 C 120 180 120 60 220 60 S 320 180 460 40");
}

.route__van,
.route__label {
  position: absolute;
  inset: 0 auto auto 0;
  offset-path: var(--route);
  offset-distance: var(--progress, 0%);
  transition: offset-distance 2.4s cubic-bezier(0.45, 0, 0.25, 1);
}

.route__van {
  offset-anchor: center;
  offset-rotate: auto -90deg;           /* artwork faces up; rotate it onto the tangent */
}

.route__label {
  offset-anchor: 50% 180%;              /* ride above the van */
  offset-rotate: 0deg;                  /* never turn text */
}

.route[data-status="delivered"] { --progress: 100%; }

@media (prefers-reduced-motion: reduce) {
  .route__van, .route__label { transition: none; }
  .route__van { offset-rotate: 0deg; }  /* no leftover diagonal angle at the destination */
}

Rendering Impact: composite. offset-rotate is applied as part of the element’s transform at each sampled distance; it adds no layout or paint, and the tangent at each point comes from geometry the browser computed once for the path.

Declaring the path once in a custom property keeps the two elements on exactly the same route. If they each carried their own copy of the path data, a later edit to one would silently separate the label from the van.

Van rotation along the route with auto, sharp corner against roundedRotation in turns over the journey. A sharp corner is a vertical jump; a rounded one spreads the turn out.Van rotation along the route with auto, sharp corner against rounded1.000.750.500.250.000.000.250.500.751.00elapsed time (fraction of duration)progresssharp cornerrounded corner
Rotation in turns over the journey. A sharp corner is a vertical jump; a rounded one spreads the turn out.

Cusps and closed loops

A path that doubles back on itself has a point where the tangent reverses. With auto, the element flips 180 degrees there in a single frame. If the artwork is symmetrical — a dot, a circle — nobody notices. For a vehicle, either split the journey into two paths so the flip happens while the element is paused or hidden, or change the path to a tight loop so the turn has somewhere to happen.

Closed paths such as circle() or a path() ending in Z have a continuous tangent everywhere except possibly at the start point. With an infinite orbit animation, check the join: if the path’s start and end directions differ, the element snaps its rotation once per revolution.

Verification checklist

Constraints and trade-offs

  • offset-rotate rotates everything inside the element, including focus rings and shadows.
  • Rounded corners change the route’s length, which changes speed through them slightly.
  • A fixed angle ignores direction completely, so arrows will point the wrong way on some legs.
  • auto depends on the tangent, which is undefined on zero-length path segments; remove degenerate segments.
  • The offset shorthand resets offset-rotate to auto if you omit it.

Frequently asked questions

Why does my element travel sideways with offset-rotate: auto?

auto aligns the element’s right-pointing x-axis with the path. If the artwork faces up, add a correcting angle such as auto -90deg.

How do I stop an element spinning at a corner?

Round the corner in the path data. The tangent changes instantly at a sharp corner, so auto rotation does too; a curve spreads the turn over several frames.

Should text use offset-rotate: auto?

No. Use a fixed angle such as 0deg. Rotating text along a path makes it hard or impossible to read, especially for people using magnification.