-
Notifications
You must be signed in to change notification settings - Fork 22.4k
/
index.md
304 lines (235 loc) · 12.4 KB
/
index.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
---
title: offset-path
slug: Web/CSS/offset-path
page-type: css-property
browser-compat: css.properties.offset-path
---
{{CSSRef}}
The **`offset-path`** [CSS](/en-US/docs/Web/CSS) property specifies a path for an element to follow and determines the element's positioning within the path's parent container or the SVG coordinate system. The path is a line, a curve, or a geometrical shape along which the element gets positioned or moves.
The `offset-path` property is used in combination with the {{cssxref("offset-distance")}}, {{cssxref("offset-rotate")}}, and {{cssxref("offset-anchor")}} properties to control the position and orientation of the element along a path.
{{EmbedInteractiveExample("pages/css/offset-path.html")}}
## Syntax
```css
/* 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(#myCircle);
/* 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;
```
### Values
The `offset-path` property takes as its value an `<offset-path>` value, a [`<coord-box>`](/en-US/docs/Web/CSS/box-edge#values) value, or both, or the `none` keyword. The `<offset-path>` value is a {{cssxref("ray","ray()")}} function, a {{cssxref("url","<url>")}} value, or a [`<basic-shape>`](/en-US/docs/Web/CSS/basic-shape) value.
- `none`
- : Specifies that the element does not follow any offset path. The `none` value is equivalent to the element not having any [offset transform](/en-US/docs/Web/CSS/offset). The element's movement in this case is determined by its default position properties, such as {{cssxref("top")}} and {{cssxref("left")}}, instead of an offset path. This is the default value.
- `<offset-path>`
- : A `ray()` function, a `<url>` value, or a `<basic-shape>` value that specifies the geometrical offset path. If omitted, the path shape for the `<coord-box>` value is `inset(0 round X)`, where `X` is the value of {{cssxref("border-radius")}} of the element that establishes the [containing block](/en-US/docs/Web/CSS/Containing_block).
- {{cssxref("ray","ray()")}}
- : Defines a line starting at a set position, of a set length, and extending at the specified angle. The `ray()` function accepts up to four parameters – an {{CSSxRef("angle")}}, an optional size value, the optional keyword `contain`, and an optional `at <position>`.
- {{cssxref("url","<url>")}}
- : Specifies the ID of an [SVG shape element](/en-US/docs/Web/SVG/Tutorial/Basic_Shapes). The path is the shape of the SVG {{SVGElement("circle")}}, {{SVGElement("ellipse")}}, {{SVGElement("line")}}, {{SVGElement("path")}}, {{SVGElement("polygon")}}, {{SVGElement("polyline")}}, or {{SVGElement("rect")}} element referenced by its `id` in the `url()` function. If the URL does not reference a shape element or is otherwise invalid, the resolved value for the offset path is `path("M0,0")` (which is a valid `<basic-shape>` value).
- {{cssxref("basic-shape")}}
- : Specifies the offset path as the equivalent path of a {{cssxref("basic-shape", "CSS basic shape function")}}, such as {{cssxref("basic-shape/circle","circle()")}}, {{cssxref("basic-shape/ellipse","ellipse()")}}, {{cssxref("basic-shape/inset","inset()")}}, {{cssxref("basic-shape/path","path()")}}, {{cssxref("basic-shape/polygon","polygon()")}}, {{cssxref("basic-shape/rect","rect()")}}, or {{cssxref("basic-shape/xywh","xywh()")}}. For example, if the `<basic_shape>` is an `ellipse()` function, then the path is the outline of the ellipse, starting at the rightmost point of the ellipse, proceeding clockwise through a full rotation. For `ellipse()` and `circle()`, which accept the `at <position>` parameter, if the `<position>` is omitted, the position defaults to `center` unless the element has an {{cssxref("offset-position")}} specified. In this case, the `offset-position` value is used for the `at <position>` parameter. More complex shapes can be defined using the {{cssxref("basic-shape/shape","shape()")}} function.
- [`<coord-box>`](/en-US/docs/Web/CSS/box-edge#values)
- : Specifies the size information of the [reference box](/en-US/docs/Web/CSS/CSS_shapes/Basic_shapes#the_reference_box) containing the path. The reference box is derived from the element that establishes the containing block for this element. This parameter is optional. If not specified, the default value is `border-box` in CSS contexts. In SVG contexts, the value is treated as `view-box`. If `ray()` or `<basic-shape>` is used to define the offset path, the `<coord-box>` value provides the reference box for the ray or the `<basic-shape>`, respectively. If `<url>` is used to define the offset path, the `<coord-box>` value provides the viewport and user coordinate system for the shape element, with the origin (`0 0`) at the top left corner and size being `1px`.
## Description
The `offset-path` property defines a path an animated element can follow. An offset path is either a specified path with one or multiple sub-paths or the geometry of a not-styled basic shape. The element's exact position on the offset path is determined by the {{cssxref("offset-distance")}} property. Each shape or path must define an initial position for the computed value of `0` for {{cssxref("offset-distance")}} and an initial direction which specifies the rotation of the object to the initial position.
Early versions of the spec called this property `motion-path`. It was changed to `offset-path` because the property describes static positions, not motion.
## Formal definition
{{cssinfo}}
## Formal syntax
{{csssyntax}}
## Examples
### Creating an offset-path using box-edge positioning
This example demonstrates using various `<coord-box>` values in the `offset-path` property.
```html hidden
<div class="box blueBox"></div>
<div class="box redBox"></div>
<div class="box greenBox"></div>
```
```css hidden
body {
width: 300px;
height: 200px;
border-radius: 50px;
border: dashed aqua;
border-width: 25px;
padding: 25px;
margin: 50px;
}
```
```css
.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%;
}
}
```
In this example, the margin, border, and padding have been purposely given large values to demonstrate the placement of the blue, green, and red rectangles on their respective `<coord-box>` edges: border-box, padding-box, and 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-coord-box.png)
#### Result
{{EmbedLiveSample('Creating an offset-path using box-edge positioning', '100%', 400)}}
### Creating an offset-path using path()
In this example, the {{svgelement("svg")}} element creates a house with a chimney and also defines two halves of a scissor. The house and chimney are composed of rectangles and polygons, and the scissor halves are represented by two distinct path elements. In the CSS code, the `offset-path` property is used to specify a path to follow for the two scissor halves. This CSS-defined path is identical to the one represented by the `<path>` element in the SVG, which is the outline of the house including the chimney.
```html live-sample___offset_path_path
<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="firstScissorHalf"
class="scissorHalf"
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"
transform="translate(0,0)"
fill="green"
stroke="black"
stroke-width="5"
stroke-linejoin="round"
stroke-linecap="round"
fill-rule="evenodd" />
<path
id="secondScissorHalf"
class="scissorHalf"
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"
transform="translate(0,0)"
fill="forestgreen"
stroke="black"
stroke-width="5"
stroke-linejoin="round"
stroke-linecap="round"
fill-rule="evenodd" />
</svg>
```
```css live-sample___offset_path_path
.scissorHalf {
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"
);
animation: followpath 4s linear infinite;
}
@keyframes followpath {
to {
offset-distance: 100%;
}
}
```
#### Result
Without the `offset-path` property, the two halves of the scissors would default to the top-left corner of the canvas. However, by using `offset-path`, the two scissor halves are aligned with the starting point of the SVG path, allowing them to move along it.
{{EmbedLiveSample('offset_path_path', '100%', '450')}}
### Creating an offset-path using url()
This example illustrates how to refer to an SVG shape to define the shape of the path that an element can follow. The green circle (defined by `.target`) follows the path of a rectangle, which is defined by passing the SVG shape's ID (`svgRect`) to the `offset-path` property by using `url()`.
The SVG rectangle that defines the path shape is shown here only to visually demonstrate that the green circle is indeed following the path defined by this rectangle.
```html live-sample___offset_path_url
<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>
</div>
```
```css hidden live-sample___offset_path_url
.outer {
position: absolute;
}
```
```css live-sample___offset_path_url
.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%;
}
}
```
{{EmbedLiveSample('live-sample___offset_path_url', '100%', '250')}}
## Specifications
{{Specifications}}
## Browser compatibility
{{Compat}}
## See also
- {{cssxref("offset")}}
- {{cssxref("offset-distance")}}
- {{cssxref("offset-rotate")}}
- [SVG \<path>](/en-US/docs/Web/SVG/Tutorial/Paths)
- {{cssxref("basic-shape/path","path()")}}
- Other demos:
- [Examples using various shapes values](https://codepen.io/team/css-tricks/pen/WZdKMq) on Codepen by CSS-Tricks
- [Moving a triangle along a curved path](https://codepen.io/ericwilligers/pen/jMbJPp) on Codepen by Eric Willigers
- [Moving a pair of scissors along the shape of a house](https://codepen.io/ericwilligers/pen/bwVZNa) on Codepen by Eric Willigers
- [Moving multiple pairs of eyes](https://jsfiddle.net/ericwilligers/r1snqdan/) on JSFiddle by Eric Willigers