1. 開発者向けのウェブ技術
  2. CSS
  3. リファレンス
  4. プロパティ
  5. offset-path

このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。

View in English Always switch to English

offset-path

Baseline 広く利用可能 *

この機能は広く実装されており、多くのバージョンの端末やブラウザーで動作します。2022年3月以降、すべてのブラウザーで利用可能です。

* この機能の一部は、対応レベルが異なる場合があります。

offset-pathCSS のプロパティで、要素がたどる経路(パス)を指定し、そのパス内の親コンテナーまたは SVG 座標系における要素の位置を決定します。パスは、要素が位置指定または移動される直線、曲線、または幾何学的形状です。

offset-path プロパティは、offset-distanceoffset-rotateoffset-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">再生</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 = "再生";
 } else {
 example.classList.add("running");
 button.textContent = "停止";
 }
});

構文

css
/* 既定値 */
offset-path: none;
/* 線の区間 */
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");
/* 基本図形 */
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);
/* 座標ボックス */
offset-path: content-box;
offset-path: padding-box;
offset-path: border-box;
offset-path: fill-box;
offset-path: stroke-box;
offset-path: view-box;
/* グローバル値 */
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 は、要素がオフセット変換を持たないことと同じです。この場合、要素の動きは、オフセットパスではなく、 topleft などの既定の位置プロパティによって決まります。これは既定値です。

<offset-path>

ray() 関数、 <url> 値、または <basic-shape> 値で、幾何学的オフセットのパスを指定します。省略した場合、 <coord-box> 値のパス形状は inset(0 round X) となります。ここで X は、包含ブロックを確立する要素の border-radius の値です。

ray()

指定した位置から、指定した長さで、指定した角度で伸びる線を定義します。 ray() 関数は、最大 4 つの引数(<angle>、オプションのサイズ値、オプションのキーワード contain、およびオプションの at <position>)を受け取ります。

<url>

SVG 図形要素の ID を指定します。パスは、 url() 関数で id によって参照される SVG <circle><ellipse><line><path><polygon><polyline><rect> のいずれかの要素の形状です。 URL が図形要素を参照していない場合、または無効な場合、オフセットパスの解決値は path("M0,0") (これは有効な <basic-shape> 値です)になります。

<basic-shape>

オフセットパスを、 CSS 基本図形関数(circle()ellipse()inset()path()polygon()rect()xywh() など)と同等のパスとして指定します。例えば、 <basic_shape>ellipse() 関数である場合、パスは、楕円の右端の点から時計回りに 1 回転した楕円の概要になります。 at <position> 引数を受け入れる ellipse() および circle() では、 <position> が省略された場合、要素に offset-position が指定されていない限り、位置は既定で center になります。この場合、 offset-position の値が at <position> 引数に使用されます。より複雑な形状は、 shape() 関数を使用して定義することができます。

<coord-box>

パスを含む参照ボックスのサイズ情報を指定します。参照ボックスは、この要素の包含ブロックを確立する要素から派生します。このパラメータはオプションです。指定しない場合、CSS コンテキストでは既定値は border-box です。 SVG のコンテキストでは、この値は view-box として扱われます。 ray() または <basic-shape> を使用してオフセットパスを定義する場合、 <coord-box> の値は、それぞれ、ray または <basic-shape> の参照ボックスを提供します。 <url> を使用してオフセットパスを定義する場合、 <coord-box> の値は、図形要素のビューポートおよびユーザー座標系を提供し、原点 (0 0) は左上隅、サイズは 1px となります。

解説

このプロパティは、移動する要素がたどることができる経路を定義します。オフセットの経路は 1 つまたは複数のサブ経路で指定された経路か、スタイル付けされていない基本図形の形状で指定します。オフセット経路上の要素の正確な位置は、 offset-distance プロパティで決定されます。それぞれの図形または経路は、初期位置を offset-distance0 の計算値で定義し、オブジェクトの回転方向を指定する初期方向を初期位置にします。

仕様書の初期の版では、このプロパティを motion-path と呼んでいました。これが offset-path と変更されたのは、このプロパティが動きではなく静的な位置を記述するからです。

公式定義

初期値 none
適用対象座標変換可能要素
継承 なし
計算値 指定通り
アニメーションの種類 計算値の型による
重ね合わせコンテキストの生成あり

形式文法

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

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

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

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

<basic-shape> =
<basic-shape-rect> |
<circle()> |
<ellipse()> |
<polygon()> |
<path()> |
<shape()>

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

<ray-size> =
<radial-extent> |
sides

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

<basic-shape-rect> =
<inset()> |
<rect()> |
<xywh()>

<circle()> =
circle( <radial-size>? [ at <position> ] ? )

<ellipse()> =
ellipse( <radial-size>? [ at <position> ] ? )

<polygon()> =
polygon( <'fill-rule'> ? [ round <length> ] ? , [ <length-percentage> <length-percentage> ] # )

<path()> =
path( <'fill-rule'> ? , <string> )

<shape()> =
shape( <'fill-rule'> ? from <position> , <shape-command># )

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

<radial-extent> =
closest-corner |
closest-side |
farthest-corner |
farthest-side

<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}

<inset()> =
inset( <length-percentage>{1,4} [ round <'border-radius'> ] ? )

<rect()> =
rect( <top> , <right> , <bottom> , <left> )

<xywh()> =
xywh( <length-percentage>{2} <length-percentage [0,∞]>{2} [ round <'border-radius'> ] ? )

<radial-size> =
<radial-extent> |
<length [0,∞]> |
<length-percentage [0,∞]>{2}

<fill-rule> =
nonzero |
evenodd

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

<shape-command> =
<move-command> |
<line-command> |
close |
<horizontal-line-command> |
<vertical-line-command> |
<curve-command> |
<smooth-command> |
<arc-command>

<border-radius> =
<length-percentage [0,∞]>{1,4} [ / <length-percentage [0,∞]>{1,4} ] ?

<move-command> =
move <command-end-point>

<line-command> =
line <command-end-point>

<horizontal-line-command> =
hline [ to [ <length-percentage> | left | center | right | x-start | x-end ] | by <length-percentage> ]

<vertical-line-command> =
vline [ to [ <length-percentage> | top | center | bottom | y-start | y-end ] | by <length-percentage> ]

<curve-command> =
curve [ [ to <position> with <control-point> [ / <control-point> ] ? ] | [ by <coordinate-pair> with <relative-control-point> [ / <relative-control-point> ] ? ] ]

<smooth-command> =
smooth [ [ to <position> [ with <control-point> ] ? ] | [ by <coordinate-pair> [ with <relative-control-point> ] ? ] ]

<arc-command> =
arc <command-end-point> [ [ of <length-percentage>{1,2} ] && <arc-sweep>? && <arc-size>? && [ rotate <angle> ] ? ]

<command-end-point> =
to <position> |
by <coordinate-pair>

<control-point> =
<position> |
<relative-control-point>

<coordinate-pair> =
<length-percentage>{2}

<relative-control-point> =
<coordinate-pair> [ from [ start | end | origin ] ] ?

<arc-sweep> =
cw |
ccw

<arc-size> =
large |
small

offset-path を box-edge の位置指定を使用して作成

この例では、offset-path プロパティでさまざまな <coord-box> 値を使用しています。

<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;
}
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%;
 }
}

この例では、マージン、境界線、およびパディングに意図的に大きな値を指定して、青、緑、赤の長方形がそれぞれの <coord-box> の辺(border-box、padding-box、content-box)に配置される様子を示しています。

[画像:青い長方形は境界線の外側の端にあり、緑色の長方形はパディングボックスの外側の端である境界線の内側の端にあり、赤い長方形はコンテンツボックスの外側の端にあります。]

結果

offset-path を path() を使用して作成

この例では、 <svg> 要素を使用して、煙突のある家と、はさみの 2 つの部分を定義しています。家と煙突は長方形と多角形で構成されており、はさみの 2 つの部分は 2 つの異なる path 要素で表現されています。CSS コードでは、 offset-path プロパティを使用して、はさみの 2 つの部分をたどるパスを指定しています。この CSS で定義されたパスは、SVG の <path> 要素で表されるパスと同一であり、これは煙突を含む家の概要です。

html
<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>
css
.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 プロパティがない場合、はさみの 2 つの半分は、既定ではキャンバスの左上隅に配置されます。しかし、 offset-path を使用すると、はさみの 2 つの半分は SVG パス開始点に配置され、パスに沿って移動できるようになります。

offset-path を url() を使用して作成

この例は、要素が辿ることができるパスの形状を定義するために SVG 形状を参照する方法を示しています。緑色の円(.target で定義)は、 SVG 形状の ID (svgRect) を offset-path プロパティに、 url() を使用して渡すことで定義された長方形のパスをたどります。

パス図形を定義する SVG 長方形は、緑色の円が実際にこの長方形によって定義されたパスに従っていることを視覚的に示すためだけにここに表示されています。

html
<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;
}
css
.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() を使用しています。

html
<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>
css
.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

ブラウザーの互換性

関連情報

MDN の改良に協力

協力方法を知る

このページは MDN の貢献者によって に最終更新されました。

AltStyle によって変換されたページ (->オリジナル) /