Spec-Zone.ru › CSS

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.

The blue rectangle sits on the outer edge of the border box, the green rectangle is on the inner border edge, which is the outer edge of the padding box, and the red rectangle is on the outer edge of the 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

См. также

  • offset
  • offset-distance
  • offset-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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API