offset

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since ⁨September 2022⁩.

The offset CSS shorthand property sets all the properties required for animating an element along a defined path. The offset properties together help to define an offset transform, a transform that aligns a point in an element (offset-anchor) to an offset position (offset-position) on a path (offset-path) at various points along the path (offset-distance) and optionally rotates the element (offset-rotate) to follow the direction of the path.

Note: Early versions of the spec called this property motion.

Try it

offset: path("M 20 60 L 120 60 L 70 10 L 20 60") 0% auto 90deg; 
offset: path( "M 20 210 L 74 210 L 118 140 \ L 62 140 L 20 210" ) 20% auto; 
<section class="default-example" id="default-example"> <div class="wrapper"> <div id="example-element"></div> </div> <button id="playback" type="button">Play</button> </section> 
#example-element { width: 24px; height: 24px; background: #2bc4a2; clip-path: polygon(0% 0%, 70% 0%, 100% 50%, 70% 100%, 0% 100%, 30% 50%); animation: distance 3000ms infinite normal ease-in-out; animation-play-state: paused; } #example-element.running { animation-play-state: running; } .wrapper { height: 220px; width: 200px; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 140" width="200" height="140"><path d="M 0 60 L 100 60 L 50 10 L 0 60" fill="none" stroke="lightgrey" stroke-width="2" stroke-dasharray="4.5"/></svg>') no-repeat, url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -140 150 230" width="200" height="230"><path d="M 0 70 L 56 70 L 98 0 L 42 0 L 0 70" fill="none" stroke="lightgrey" stroke-width="2" stroke-dasharray="4.5"/></svg>'); } @keyframes distance { to { offset-distance: 100%; } } #playback { position: absolute; top: 0; left: 0; font-size: 1em; } 
const example = document.getElementById("example-element"); const button = document.getElementById("playback"); button.addEventListener("click", () => { if (example.classList.contains("running")) { example.classList.remove("running"); button.textContent = "Play"; } else { example.classList.add("running"); button.textContent = "Pause"; } }); 

Constituent properties

This property is a shorthand for the following CSS properties:

Syntax

css
/* Offset position */ offset: auto; offset: 10px 30px; offset: none; /* Offset path */ offset: ray(45deg closest-side); offset: path("M 100 100 L 300 100 L 200 300 z"); offset: url("arc.svg"); /* Offset path with distance and/or rotation */ offset: url("circle.svg") 100px; offset: url("circle.svg") 40%; offset: url("circle.svg") 30deg; offset: url("circle.svg") 50px 20deg; /* Including offset anchor */ offset: ray(45deg closest-side) / 40px 20px; offset: url("arc.svg") 2cm / 0.5cm 3cm; offset: url("arc.svg") 30deg / 50px 100px; /* Global values */ offset: inherit; offset: initial; offset: revert; offset: revert-layer; offset: unset; 

Formal definition

Initial valueas each of the properties of the shorthand:
Applies totransformable elements
Inheritedno
Percentagesas each of the properties of the shorthand:
Computed valueas each of the properties of the shorthand:
Animation typeas each of the properties of the shorthand:
Creates stacking contextyes

Formal syntax

offset = 
[ <'offset-position'>? [ <'offset-path'> [ <'offset-distance'> || <'offset-rotate'> ]? ]? ]! [ / <'offset-anchor'> ]?

<offset-position> =
normal |
auto |
<position>

<offset-path> =
none |
<offset-path> || <coord-box>

<offset-distance> =
<length-percentage>

<offset-rotate> =
[ auto | reverse ] ||
<angle>

<offset-anchor> =
auto |
<position>

<position> =
<position-one> |
<position-two> |
<position-four>

<offset-path> =
<ray()> |
<url> |
<basic-shape>

<coord-box> =
<paint-box> |
view-box

<length-percentage> =
<length> |
<percentage>

<position-one> =
left |
center |
right |
top |
bottom |
x-start |
x-end |
y-start |
y-end |
block-start |
block-end |
inline-start |
inline-end |
<length-percentage>

<position-two> =
[ left | center | right | x-start | x-end ] && [ top | center | bottom | y-start | y-end ] |
[ left | center | right | x-start | x-end | <length-percentage> ] [ top | center | bottom | y-start | y-end | <length-percentage> ] |
[ block-start | center | block-end ] && [ inline-start | center | inline-end ] |
[ start | center | end ]{2}

<position-four> =
[ [ left | right | x-start | x-end ] <length-percentage> ] && [ [ top | bottom | y-start | y-end ] <length-percentage> ] |
[ [ block-start | block-end ] <length-percentage> ] && [ [ inline-start | inline-end ] <length-percentage> ] |
[ [ start | end ] <length-percentage> ]{2}

<ray()> =
ray( <angle> &&
<ray-size>? &&
contain? &&
[ at <position> ]? )

<paint-box> =
<visual-box> |
fill-box |
stroke-box

<ray-size> =
closest-side |
closest-corner |
farthest-side |
farthest-corner |
sides

<visual-box> =
content-box |
padding-box |
border-box

Examples

Animating an element along a path

HTML

html
<div id="offsetElement"></div> 

CSS

css
@keyframes move { from { offset-distance: 0%; } to { offset-distance: 100%; } } #offsetElement { width: 50px; height: 50px; background-color: blue; offset: path("M 100 100 L 300 100 L 200 300 z") auto; animation: move 3s linear infinite; } 

Result

Specifications

Specification
Motion Path Module Level 1
# offset-shorthand

Browser compatibility

See also