CSS-свойство `offset-path`
Базовая поддержка Широко доступно
Эта функция хорошо зарекомендовала себя и работает на многих устройствах и в различных версиях браузеров. Она доступна во всех браузерах с сентября 2022 года.
offset-path — свойство CSS, которое задаёт путь, по которому следует элемент, и определяет его положение внутри родительского контейнера пути или в системе координат SVG. Путь представляет собой линию, кривую или геометрическую фигуру, вдоль которой располагается или перемещается элемент.
Свойство offset-path используется вместе со свойствами offset-distance, offset-rotate и offset-anchor, чтобы управлять положением и ориентацией элемента вдоль пути.
Попробуйте
offset-path: path("M-70,-40 C-70,70 70,70 70,-40");
offset-path: path("M0,0 L60,70 L-60,30z");
<section class="default-example" id="default-example"> <div class="transition-all" id="example-element"></div> <button id="playback" type="button">Play</button> </section>
#example-element {
width: 24px;
height: 24px;
background: #2bc4a2;
animation: distance 8000ms infinite linear;
animation-play-state: paused;
clip-path: polygon(0% 0%, 70% 0%, 100% 50%, 70% 100%, 0% 100%, 30% 50%);
}
#example-element.running {
animation-play-state: running;
}
#playback {
position: absolute;
top: 0;
left: 0;
font-size: 1em;
}
@keyframes distance {
0% {
offset-distance: 0%;
}
100% {
offset-distance: 100%;
}
}
#default-example {
position: relative;
}
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";
}
});
Синтаксис
/* Default */
offset-path: none;
/* Line segment */
offset-path: ray(45deg closest-side contain);
offset-path: ray(contain 150deg at center center);
offset-path: ray(45deg);
/* URL */
offset-path: url("#my-circle");
/* Basic shape */
offset-path: circle(50% at 25% 25%);
offset-path: ellipse(50% 50% at 25% 25%);
offset-path: inset(50% 50% 50% 50%);
offset-path: polygon(30% 0%, 70% 0%, 100% 50%, 30% 100%, 0% 70%, 0% 30%);
offset-path: path("M 0,200 Q 200,200 260,80 Q 290,20 400,0 Q 300,100 400,200");
offset-path: rect(5px 5px 160px 145px round 20%);
offset-path: xywh(0 5px 100% 75% round 15% 0);
/* Coordinate box */
offset-path: content-box;
offset-path: padding-box;
offset-path: border-box;
offset-path: fill-box;
offset-path: stroke-box;
offset-path: view-box;
/* Global values */
offset-path: inherit;
offset-path: initial;
offset-path: revert;
offset-path: revert-layer;
offset-path: unset;
Значения
Свойство offset-path принимает значение типа <offset-path>, значение типа <coord-box> или оба значения либо ключевое слово none. Значение <offset-path> представляет собой функцию ray(), значение <url> или значение <basic-shape>.
-
none - Указывает, что элемент не следует ни по одному пути смещения. Значение
noneэквивалентно отсутствию у элемента какого-либо преобразования смещения. В этом случае перемещение элемента определяется его свойствами положения по умолчанию, такими какtopиleft, а не путём смещения. Это значение используется по умолчанию. -
<offset-path> - Функция
ray(), значение<url>или значение<basic-shape>, задающее геометрический путь смещения. Если оно не указано, форма пути для значения<coord-box>—inset(0 round X), гдеX— значение свойстваborder-radiusэлемента, задающего контейнерный блок.-
ray() - Задаёт линию, которая начинается в указанном положении, имеет заданную длину и продолжается под заданным углом. Функция
ray()принимает до четырёх параметров:<angle>, необязательное значение размера, необязательное ключевое словоcontainи необязательный параметрat <position>. -
<url> - Задаёт идентификатор элемента фигуры SVG. Путь соответствует фигуре элемента SVG
<circle>,<ellipse>,<line>,<path>,<polygon>,<polyline>или<rect>, на который ссылается егоidв функцииurl(). Если URL не ссылается на элемент фигуры или недопустим по другой причине, вычисленное значение для пути смещения будетpath("M0,0")(это допустимое значение<basic-shape>). -
<basic-shape> - Задаёт путь смещения, эквивалентный пути функции базовой фигуры CSS, например
circle(),ellipse(),inset(),path(),polygon(),rect()илиxywh(). Например, если<basic_shape>— функцияellipse(), путь представляет собой контур эллипса, который начинается в его крайней правой точке и проходит полный оборот по часовой стрелке. Дляellipse()иcircle(), принимающих параметрat <position>, если<position>не задано, положение по умолчанию —center, если только для элемента не указано свойствоoffset-position. В этом случае для параметраat <position>используется значениеoffset-position. Более сложные фигуры можно задать с помощью функцииshape().
-
-
<coord-box> - Задаёт размеры опорного блока, содержащего путь. Опорный блок определяется элементом, который задаёт контейнерный блок для этого элемента. Этот параметр необязателен. Если он не указан, в контексте CSS по умолчанию используется значение
border-box. В контексте SVG значение интерпретируется какview-box. Если для задания пути смещения используетсяray()или<basic-shape>, значение<coord-box>задаёт опорный блок для луча или<basic-shape>соответственно. Если для задания пути смещения используется<url>, значение<coord-box>задаёт область просмотра и пользовательскую систему координат для элемента фигуры: начало координат (0 0) находится в левом верхнем углу, а размер равен1px.
Описание
Свойство offset-path задаёт путь, по которому может следовать анимируемый элемент. Путь смещения — это либо заданный путь с одним или несколькими подпутями, либо геометрия не стилизованной базовой фигуры. Точное положение элемента на пути смещения определяется свойством offset-distance. Для вычисленного значения 0 каждая фигура или путь должны задавать начальное положение для offset-distance и начальное направление, которое определяет поворот объекта относительно начального положения.
В ранних версиях спецификации это свойство называлось motion-path. Название изменили на offset-path, поскольку свойство описывает статические положения, а не движение.
Формальное определение
| Исходное значение | none |
|---|---|
| Применяется к | преобразуемым элементам |
| Наследуется | нет |
| Вычисленное значение | как задано |
| Тип анимации | по типу вычисленного значения |
Формальный синтаксис
offset-path = none | <offset-path> || <coord-box> <coord-box> = <paint-box> | view-box <paint-box> = <visual-box> | fill-box | stroke-box <visual-box> = content-box | padding-box | border-box
Примеры
Создание offset-path с помощью позиционирования относительно границ блока
В этом примере показано использование различных значений <coord-box> для свойства offset-path.
<div class="box blueBox"></div> <div class="box redBox"></div> <div class="box greenBox"></div>
body {
width: 300px;
height: 200px;
border-radius: 50px;
border: dashed aqua;
border-width: 25px;
padding: 25px;
margin: 50px;
}
.box {
width: 40px;
height: 20px;
animation: move 8000ms infinite ease-in-out;
}
.blueBox {
background-color: blue;
offset-path: border-box;
offset-distance: 5%;
}
.greenBox {
background-color: green;
offset-path: padding-box;
offset-distance: 8%;
}
.redBox {
background-color: red;
offset-path: content-box;
offset-distance: 12%;
}
@keyframes move {
0%,
20% {
offset-distance: 0%;
}
80%,
100% {
offset-distance: 100%;
}
}
В этом примере намеренно заданы большие значения отступа, границы и внутреннего отступа, чтобы продемонстрировать расположение синих, зелёных и красных прямоугольников относительно соответствующих границ <coord-box>: border-box, padding-box и content-box.

Результат
Создание offset-path с помощью path()
В этом примере элемент <svg> создаёт дом с дымоходом, а также задаёт две половинки ножниц. Дом и дымоход состоят из прямоугольников и многоугольников, а половинки ножниц представлены двумя отдельными элементами path. В коде CSS свойство offset-path задаёт путь, по которому должны следовать две половинки ножниц. Этот путь, заданный в CSS, совпадает с путём элемента <path> в SVG, который представляет собой контур дома вместе с дымоходом.
<svg
xmlns="http://www.w3.org/2000/svg"
width="700"
height="450"
viewBox="350 0 1400 900">
<title>House and Scissors</title>
<rect x="595" y="423" width="610" height="377" fill="blue" />
<polygon points="506,423 900,190 1294,423" fill="yellow" />
<polygon points="993,245 993,190 1086,190 1086,300" fill="red" />
<path
id="house"
d="M900,190 L993,245 V201 A11,11 0 0,1 1004,190 H1075 A11,11 0 0,1 1086,201 V300 L1294,423 H1216 A11,11 0 0,0 1205,434 V789 A11,11 0 0,1 1194,800 H606 A11,11 0 0,1 595,789 V434 A11,11 0 0,0 584,423 H506 L900,190"
fill="none"
stroke="black"
stroke-width="13"
stroke-linejoin="round"
stroke-linecap="round" />
<path
id="first-scissor-half"
class="scissor-half"
d="M30,0 H-10 A10,10 0 0,0 -20,10 A20,20 0 1,1 -40,-10 H20 A10,10 0 0,1 30,0 M-40,20 A10,10 1 0,0 -40,0 A10,10 1 0,0 -40,20 M0,0" />
<path
id="second-scissor-half"
class="scissor-half"
d="M30,0 H-10 A10,10 0 0,1 -20,-10 A20,20 0 1,0 -40,10 H20 A10,10 0 0,0 30,0 M-40,-20 A10,10 1 0,0 -40,0 A10,10 1 0,0 -40,-20 M0,0" />
</svg>
.scissor-half {
offset-path: path(
"M900,190 L993,245 V201 A11,11 0 0,1 1004,190 H1075 A11,11 0 0,1 1086,201 V300 L1294,423 H1216 A11,11 0 0,0 1205,434 V789 A11,11 0 0,1 1194,800 H606 A11,11 0 0,1 595,789 V434 A11,11 0 0,0 584,423 H506 L900,190"
);
transform: translate(0px, 0px);
fill: green;
stroke: black;
stroke-width: 5px;
stroke-linejoin: round;
stroke-linecap: round;
fill-rule: evenodd;
offset-anchor: 0 0;
}
#first-scissor-half {
animation:
move 12s linear infinite,
rotate-left 1s infinite;
}
#second-scissor-half {
animation:
move 12s linear infinite,
rotate-right 1s infinite;
}
@keyframes move {
from {
offset-distance: 0%;
}
to {
offset-distance: 100%;
}
}
@keyframes rotate-left {
0% {
offset-rotate: auto 0deg;
}
50% {
offset-rotate: auto -45deg;
}
100% {
offset-rotate: auto 0deg;
}
}
@keyframes rotate-right {
0% {
offset-rotate: auto 0deg;
}
50% {
offset-rotate: auto 45deg;
}
100% {
offset-rotate: auto 0deg;
}
}
Результат
Без свойства offset-path обе половинки ножниц располагались бы в левом верхнем углу холста. Однако благодаря offset-path они выравниваются с начальной точкой пути SVG, что позволяет им двигаться вдоль него.
Создание offset-path с помощью url()
В этом примере показано, как сослаться на фигуру SVG, чтобы задать путь, по которому может следовать элемент. Зелёный круг (заданный с помощью .target) следует по пути прямоугольника. Прямоугольник задаётся передачей идентификатора фигуры SVG (svgRect) свойству offset-path с помощью url().
Прямоугольник SVG, задающий форму пути, показан здесь только для наглядности — чтобы продемонстрировать, что зелёный круг действительно следует по заданному им пути.
<div class="outer"> <div class="target"></div> </div> <svg width="400" height="200" xmlns="http://www.w3.org/2000/svg"> <rect id="svgRect" x="50" y="50" width="200" height="100" /> </svg>
.outer {
position: absolute;
}
.target {
width: 50px;
height: 50px;
border-radius: 50%;
background-color: green;
offset-path: url("#svgRect");
offset-anchor: auto;
animation: move 5s linear infinite;
}
#svgRect {
fill: antiquewhite;
stroke: black;
stroke-width: 2;
}
@keyframes move {
0% {
offset-distance: 0%;
}
100% {
offset-distance: 100%;
}
}
Различные фигуры
В этом примере используются различные значения <basic-shape>: circle(), ellipse(), inset(), polygon().
<div class="container"> <div class="mover mover-path">path()</div> <div class="mover mover-circle">circle()</div> <div class="mover mover-ellipse">ellipse()</div> <div class="mover mover-inset">inset()</div> <div class="mover mover-polygon">polygon()</div> </div>
.container {
border: 1px solid black;
width: 80vw;
height: 80vh;
position: relative;
left: 10vw;
top: 10vh;
}
.mover {
width: 100px;
height: 80px;
border-radius: 50%;
line-height: 80px;
text-indent: 10px;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' id='e644da42-a34e-4ceb-a89a-89a4eb6dcc51' data-name='Layer 1' viewBox='0 0 71.08 54.62'%3E%3Ctitle%3Epointer-hand%3C/title%3E%3Cpath d='M43.56,49.35a5.24,5.24,0,0,0-1.27-3.43,5.26,5.26,0,0,0,1.86-9,5.26,5.26,0,0,0-.5-9.53L66.12,27c2.28-.07,5-1.57,5-4.58a5.06,5.06,0,0,0-4.58-4.83L34.08,17c3.48-2.89,6.26-6.55,6.73-11.08C41.45-.14,36.07-1.15,35,1.09,32,7.11,23,12.75,17.42,15.52,8.64,19.08,0,19.77,0,34.56,0,42.7,2.7,47.94,9.42,51c5.51,2.52,13.71,3.59,25.36,3.59H38.3A5.27,5.27,0,0,0,43.56,49.35Z'/%3E%3C/svg%3E")
no-repeat;
background-size: cover;
color: white;
animation: move 10s linear infinite;
font-family: monospace;
position: absolute;
left: 50%;
transform: translateX(-50%);
transform-origin: center center;
}
.mover-path {
top: 50px;
motion-path: path(
"M18.45,58.46s52.87-70.07,101.25-.75,101.75-6.23,101.75-6.23S246.38,5.59,165.33,9.08s-15,71.57-94.51,74.56S18.45,58.46,18.45,58.46Z"
);
offset-path: path(
"M18.45,58.46s52.87-70.07,101.25-.75,101.75-6.23,101.75-6.23S246.38,5.59,165.33,9.08s-15,71.57-94.51,74.56S18.45,58.46,18.45,58.46Z"
);
}
.mover-circle {
top: 150px;
offset-path: circle(100px at 50px 50px);
motion-path: circle(100px at 50px 50px);
}
.mover-ellipse {
top: 250px;
offset-path: ellipse(25% 40% at 50% 50%);
motion-path: ellipse(25% 40% at 50% 50%);
}
.mover-inset {
top: 350px;
offset-path: inset(5% 20% 15% 10%);
motion-path: inset(5% 20% 15% 10%);
}
.mover-polygon {
top: 450px;
offset-path: polygon(
30% 0%,
70% 0%,
100% 30%,
100% 70%,
70% 100%,
30% 100%,
0% 70%,
0% 30%
);
motion-path: polygon(
30% 0%,
70% 0%,
100% 30%,
100% 70%,
70% 100%,
30% 100%,
0% 70%,
0% 30%
);
}
@keyframes move {
100% {
motion-offset: 100%;
offset-distance: 100%;
}
}
Спецификации
| Спецификация |
|---|
| Motion Path Module Level 1 # offset-path-property |
Совместимость с браузерами
| Компьютеры | Мобильные устройства | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome для Android | Firefox для Android | Opera для Android | Safari на iOS | Samsung Internet | WebView для Android | WebView на iOS | |
offset-path |
55
46
|
79
79
|
72 |
45
32
|
15.4 |
55
46
|
79 |
43
32
|
15.4 |
6.0path() — единственный поддерживаемый тип значения.5.0
|
55
46
|
15.4 |
basic_shape |
116 |
116 |
122 |
102 |
18 |
116 |
122 |
78 |
18 |
24.0 |
116 |
18 |
border-box |
116 |
116 |
122 |
102 |
18 |
116 |
122 |
78 |
18 |
24.0 |
116 |
18 |
content-box |
116 |
116 |
122 |
102 |
18 |
116 |
122 |
78 |
18 |
24.0 |
116 |
18 |
fill-box |
116 |
116 |
122 |
102 |
18 |
116 |
122 |
78 |
18 |
24.0 |
116 |
18 |
margin-box |
Нет |
Нет |
Нет |
Нет |
18 |
Нет |
Нет |
Нет |
18 |
Нет |
Нет |
18 |
none |
80 |
80 |
72 |
67 |
18 |
80 |
79 |
57 |
18 |
13.0 |
80 |
18 |
padding-box |
116 |
116 |
122 |
102 |
18 |
116 |
122 |
78 |
18 |
24.0 |
116 |
18 |
path |
64 |
79 |
72 |
51 |
16 |
64 |
79 |
47 |
16 |
9.0 |
64 |
16 |
ray |
116 |
116 |
122 |
102 |
16 |
116 |
122 |
78 |
16 |
24.0 |
116 |
16 |
stroke-box |
116 |
116 |
122 |
102 |
18 |
116 |
122 |
78 |
18 |
24.0 |
116 |
18 |
url |
116 |
116 |
122 |
102 |
17 |
116 |
122 |
78 |
17 |
24.0 |
116 |
17 |
view-box |
116 |
116 |
122 |
102 |
18 |
116 |
122 |
78 |
18 |
24.0 |
116 |
18 |
См. также
offsetoffset-distanceoffset-rotate- Руководство по путям SVG
path()
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/offset-path