モーションパスモジュール レベル 1

W3C ワーキングドラフト

この文書の詳細情報
このバージョン:
https://www.w3.org/TR/2024/WD-motion-1-20241105/
最新公開バージョン:
https://www.w3.org/TR/motion-1/
編集者草案:
https://drafts.fxtf.org/motion-1/
履歴:
https://www.w3.org/standards/history/motion-1/
テストスイート:
https://github.com/web-platform-tests/wpt/tree/master/css/motion
https://wpt.fyi/results/css/motion/
フィードバック:
GitHub
仕様内でインライン
編集者:
(Adobe Inc.)
(Igalia)
Tab Atkins-Bittner (Google)
以前の編集者:
(Google)
(元 Google)
課題管理:
GitHub 課題
この仕様への編集提案:
GitHub 編集者

概要

モーションパスは、著者が任意のグラフィカルオブジェクトを配置し、著者が指定したパスに沿ってアニメーションさせることを可能にします。

この文書の位置付け

このセクションは、本書が公開された時点での文書の位置付けについて説明します。 現在のW3C出版物の一覧と本技術レポートの最新改訂版は、 https://www.w3.org/TR/ のW3C技術レポート一覧で確認できます。

ワーキングドラフトとして公開されていることは、W3Cおよびその会員による承認を意味するものではありません。本書はドラフト文書であり、随時更新、置換、廃止される可能性があります。本書を進行中の作業以外として引用するのは不適切です。

この仕様に関する議論には、GitHub Issuesを利用することが推奨されます。 Issueを提出する際は、タイトルに「motion」という文言を含めてください(例:「[motion] …コメントの概要…」)。 すべてのIssueとコメントはアーカイブされています。 また、過去のアーカイブもあります。

本書はCSS作業グループによって、勧告プロセスに基づきワーキングドラフトとして公開されました。

本書はW3C特許ポリシーに基づき運用されるグループによって作成されました。 W3Cは、グループの成果物に関連して提出された特許開示の公開リストを管理しています。 そのページには特許開示の方法も記載されています。個人が本質的な特許請求項(Essential Claim(s))を含むと判断した場合は、W3C特許ポリシー第6節に従って情報を開示しなければなりません。

本書は2023年11月3日W3Cプロセス文書に従って管理されています。

1. はじめに

このセクションは規定的ではありません。

transform プロパティおよび関連プロパティは、 boxを 配置された位置に対して任意の位置に再配置 (および回転、拡大縮小など) することを可能にし、 他のページ要素のレイアウトを妨げることなく操作できます。 これらの位置はCSSでアニメーションやトランジションが可能ですが、 比較的単純な方法しかできません: boxを開始位置から終了位置まで直線で移動させるだけです。

この仕様は offset ショートハンドと、 関連するロングハンドプロパティの一式を導入します。 これらは offset transform を定義します: 要素の特定のポイント (offset-anchor) を パス 上の offset position (offset-pathoffset-distance) に 揃えて配置し、必要に応じてパスの方向に回転させます (offset-rotate)。

これにより、 強力な新しい変形方法が可能になります。 例えば、標準の矩形座標ではなく ray() 関数を使った 極座標による配置や、 要素を定義されたパスに沿ってアニメーションさせることができ、 複雑かつ美しい2次元空間遷移を簡単に定義できます。

例えば、 以下の図は曲線のパス (点線で示されています) と、パス上の様々な位置に配置された飛行機のグラフィックを示しています。 飛行機はパス上の各位置でパスの進行方向を向いています。
例のパス

飛行機は異なる offset-distance の値: 0%, 50%, 100% で表示されています。

1.1. モジュールの相互作用

この仕様は要素に適用できる追加の変形タイプを定義します (詳細は [css-transforms-1] を参照)。

CSS Transforms 2 § 6 Current Transformation Matrix で説明されているように、 本書で定義される変形は 個々の変形プロパティ (translate/rotate/scale (定義は [css-transforms-2])) の後、transform プロパティ (定義は [css-transforms-1]) の前にレイヤーされます。

1.2.

この仕様は CSSプロパティ定義規則 ([CSS21]) に従います。 <basic-shape> 型は CSS Shapes Module Level 1 [CSS-SHAPES] で定義されています。 <coord-box> 型は CSS Box Model Module Level 3 [CSS-BOX-3] で定義されています。 これらの仕様で定義されていない値型は CSS Values and Units Module Level 3 [CSS3VAL] で定義されています。

各プロパティ定義に記載された特定値に加えて、本仕様で定義される全プロパティは initialinherit など CSS全体キーワードもプロパティ値として受け入れます ([CSS3VAL])。 可読性のため明示的には繰り返し記載していません。

2. モーションパス

2.1. パスの定義: offset-path プロパティ

名前: offset-path
値: none | <offset-path> || <coord-box>
初期値: none
適用対象: 変形可能な要素
継承: no
パーセンテージ: n/a
算出値: 指定通り
正規順序: 文法通り
アニメーション型: 算出値ごと
メディア: visual

offset path を指定し、 boxが配置される幾何学的なパスを定義します。

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

値の意味は以下の通りです:

none

要素は offset transform を持ちません。

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

要素は offset transform を持ち、 何らかの offset path により定義されます。 § 2.7 オフセット変換の計算 を参照してください。

transform を持つ通常の効果 (例えば 積み重ねコンテキスト の生成など) も適用されます。 詳細は CSS Transforms 1 § 3 変形レンダリングモデル を参照。

<offset-path> が省略された場合、 デフォルトは inset(0 round X) となり、 X はこの要素の border-radius の値です。 包含ブロック を定める要素に基づきます。 <coord-box> が省略された場合、 デフォルトは border-box です。

各構成要素の解釈については以下の個別値を参照してください。

<ray()>

offset pathorigin から ある角度に向かって伸びる直線です。 詳細は § 2.1.1 ray() 関数 を参照してください。

<coord-box> は rayの 参照ボックス を提供します。

<url>

SVGの shape element へのURL参照です。 offset path は 参照された要素の 等価なパス となります。[SVG2]

URLが shape element を参照しない場合 (他の要素を参照した場合や非SVG文書に解決した場合、解決できない場合など)、 path("m 0 0") (<basic-shape>) として動作します。

<coord-box>shape element のビューポートおよびユーザー座標系を定義し、 原点 (0,0) は左上隅にあり、 単位は 1px です。

<basic-shape>

offset path等価なパス です。 <basic-shape> 関数のもの。

全ての <basic-shape>at <position> 引数が省略され、 かつ要素が offset starting positionoffset-position で定義していれば、 その引数には指定された offset starting position が使われます。 それ以外は各関数の仕様通りのデフォルトになります。

<coord-box><basic-shape> の参照ボックスを提供します。

<coord-box>

<offset-path> がサイズ指定に使うボックスを定義します。

CSSの文脈では、 参照されるボックスは この要素の 包含ブロック を定める要素のものです。

SVGの文脈では、 全ての値は view-box として振る舞います。

テスト

2.1.1. ray() 関数

ray() 関数は、 offset path を ある点から定義された角度で伸びる直線として定義します。

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

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

引数は次の通りです:

<angle>

offset pathoffset starting position から始まり、 指定された <angle> の 方向に進む単一の線分です。 (長さは他の引数によって決まります。) グラデーション関数 と同様に、 <angle> の値は方位角として解釈され、 0deg は上向き、 正の角度が時計回りの回転を表します。

<ray-size>

offset path の長さ (offset-distance: 0%offset-distance: 100% の間の距離) を包含ブロックに対して指定します。

<ray-size> が指定されていない場合、デフォルトは closest-side です。

注: sides の場合、 距離は指定された <angle> によって変化します。 他の値の場合は、<angle> に関係なく距離は一定です。

各キーワードの意味は次の通りです:

closest-side

ray の開始点から 包含ブロック の最も近い辺までの距離です。

closest-corner

ray の開始点から 包含ブロック の最も近い角までの距離です。

farthest-side

ray の開始点から 包含ブロック の最も遠い辺までの距離です。

farthest-corner

ray の開始点から 包含ブロック の最も遠い角までの距離です。

sides

ray の開始点から offset path包含ブロック の境界と交差する点までの距離です。

ray の開始点が 包含ブロック の境界上、 または境界外にある場合は、 距離はゼロになります。

注: closest-sideclosest-corner の場合、 ray の開始点が辺や角の上にある場合、 それが最も近いものとなります。 (つまり距離はゼロです。)

注: closest-sidefarthest-side の場合、 ray の開始点が 包含ブロック の外にある場合、 包含ブロック の端は無限まで伸びているとみなされます。

contain

offset path の長さが 包含ブロック の中に offset-distance: 100% でも 要素が収まるように短くなります。

具体的には、パスの長さは 要素のボーダーボックスの幅または高さのうち大きい方の半分だけ短くなり、 最低値はゼロです。

この振る舞いは特定のケース(要素の幅と高さが等しいかほぼ等しい場合、 border-radius により完全に丸みを帯びているか、角が見た目に影響しない場合、 ray()closest-side の位置指定を使う場合、 offset-anchorcenter の場合) に最適化されています。

これらの条件下では、 (例えば丸い時計の縁に要素を配置するなど) 各要素が offset-distance: 100% の時に 時計の内縁ぎりぎりに配置されることを保証します。

他の条件でも似たような動作になりますが、最適とは限りません。

at <position>

ray の origin(始点、0% の位置)を指定します。 <position> に従い、 ボックスの 包含ブロック 内に 0x0 のオブジェクト領域を配置して解決されます。

省略された場合は、 要素の offset starting position (offset-position で指定) を使います。

要素が offset starting position を持たない場合は、 at center として振る舞います。

注: ray() は現在 offset path としてのみ使用可能です。 将来的に他の用途に拡張された場合も、 offset-position の利用は offset path の場合に限定されます。 他の <basic-shape> 関数と同様です。

テスト

これらの例はすべて書き直す必要があります。

いくつかの例を示します。最初の例では、ボックスの一部が offset path の外側にあることが分かります。
<style>
    body {
        transform-style: preserve-3d;
        width: 200px;
        height: 200px;
    }
    .box {
        width: 50px;
        height: 50px;
        offset-position: 50% 50%;
        offset-distance: 100%;
        offset-rotate: 0deg;
    }
    #redBox {
        background-color: red;
        offset-path: ray(45deg closest-side);
    }
    #blueBox {
        background-color: blue;
        offset-path: ray(180deg closest-side);
    }
</style>
<body>
    <div class="box" id="redBox"></div>
    <div class="box" id="blueBox"></div>
</body>
containなしで配置されたボックスの画像
offset-pathcontainなし)

2番目の例では、各ボックスの containoffset-path の値に指定することで、はみ出しを防いでいます。

<style>
    body {
        transform-style: preserve-3d;
        width: 200px;
        height: 200px;
    }
    .box {
        width: 50px;
        height: 50px;
        offset-position: 50% 50%;
        offset-distance: 100%;
        offset-rotate: 0deg;
    }
    #redBox {
        background-color: red;
        offset-path: ray(45deg closest-side contain);
    }
    #blueBox {
        background-color: blue;
        offset-path: ray(180deg closest-side contain);
    }
</style>
<body>
    <div class="box" id="redBox"></div>
    <div class="box" id="blueBox"></div>
</body>
containで配置されたボックスの画像
offset-pathcontainあり)

3番目の例では、パスサイズが大きくされてボックスが収まるようになっています。used offset distance は負の値です。

<style>
    body {
        transform-style: preserve-3d;
        width: 250px;
        height: 250px;
    }
    .box {
        width: 60%;
        height: 10%;

        offset-position: 20% 20%;
        offset-distance: 0%;
        offset-rotate: 0deg;
        offset-anchor: 200% -300%;
    }
    #blueBox {
        background-color: blue;
        offset-path: ray(-90deg closest-side contain);
    }
</style>
<body>
    <div class="box" id="blueBox"></div>
</body>
パスサイズを増やした画像
offset-path(パスサイズ増加)

4番目の例では、初期位置が包含ブロックの外側にあります。

<style>
    #container {
        transform-style: preserve-3d;
        width: 200px;
        height: 200px;
    }
    .box {
        width: 20%;
        height: 20%;
        offset-position: 140% 70%;
        offset-distance: 100%;
    }
    #redBox {
        background-color: red;
        offset-path: ray(-90deg sides);
    }
    #blueBox {
        background-color: blue;
        offset-path: ray(180deg closest-side);
    }
</style>
<div id="container">
    <div class="box" id="redBox"></div>
    <div class="box" id="blueBox"></div>
</div>
初期位置が包含ブロック外の画像
初期位置が包含ブロックの外側

2.1.2. <basic-shape>配置の例

この例では、暗黙的な中心位置を持つ円を使用しています。
<style>
    body {
        width: 323px;
        height: 131px;
        margin: 0px;
        border: 2px solid black;
        padding: 8px;
        transform-style: preserve-3d;
    }
    .item {
        width:  90px;
        height: 40px;
        background-color: violet;
    }
    #middle {
        offset-position: auto;
        offset-path: circle(60%) margin-box;
        offset-distance: 25%;
        offset-anchor: left top;
    }
</style>
<body>
    <div class="item"></div>
    <div class="item" id="middle"></div>
    <div class="item"></div>
</body>
通常フローで円の中心を決定する画像
円の中心は通常のフローで決定されます。

2.1.3. <coord-box>配置の例

この例は、<coord-box>offset pathborder-radius と組み合わせてどのように動作するかを示しています。
<style>
    body {
        width: 500px;
        height: 300px;
        border-radius: 80px;
        border: dashed aqua;
        margin: 0;
    }
    #blueBox {
        width: 40px;
        height: 20px;
        background-color: blue;
        offset-path: margin-box;
    }
</style>
<body>
    <div id="blueBox"></div>
</body>
border-radius付きgeometry-boxの例の画像
初期位置は上部水平線の左端です。

2.2. パス上の位置: offset-distance プロパティ

名前: offset-distance
値: <length-percentage>
初期値: 0
適用対象: 変形可能な要素
継承: no
パーセンテージ: offset path の長さに対する割合
算出値: 算出された<length-percentage>
正規順序: 文法通り
アニメーション型: 算出値ごと
メディア: visual

offset path に沿ってoffset positionがどこにあるかを指定します。

<length-percentage>

offset position は、 要素の offset path に沿った 指定された距離の位置です。 パス上の距離の計算については§ 2.2.1 パスに沿った算出距離の計算を参照してください。

パーセンテージは offset path の全長に対する割合です。

テスト

注: offset-distance をアニメーションさせることで、要素は複雑なパスを簡単にたどることができます。

要素に offset path がない場合、このプロパティは何も行いません。

2.2.1. パスに沿った算出距離の計算

offset path に沿った距離の処理は、offset path の性質によって異なります:

与えられた offset pathoffset distance に対する used offset distance を決定するには:

  1. total lengthoffset path の全サブパスを含む総距離とする。

  2. offset distance をピクセルに変換し、100%は total length に変換する。

  3. もし offset path が無限のrayなら:

    used offset distanceoffset distance と同じにする。

    それ以外で offset path が contain付きの <angle> パスなら:

    used offset distanceoffset distance にし、ボックスがパス内に完全に収まるよう制限する。

    他の閉じていない区間なら:

    used offset distanceoffset distance にし、0からパスの総距離で制限する。

    それ以外は offset path が閉じたループ:

    used offset distanceoffset distance をパスの総距離で割った余り(modulo)とする。パスの総距離が0なら、used offset distance も0。

    注: ここでの「modulo」は数学的な定義で、出力は常に非負です。

この例は、閉じていない区間に沿って配置されたボックスを示しています。
<style>
    .item {
        width: 100px;
        height: 40px;
        offset-position: 0% 0%;
        offset-path: path('m 0 0 h 200 v 150');
    }
    #box1 {
        background-color: red;
        offset-distance: -280%;
    }
    #box2 {
        background-color: green;
        offset-distance: 190%;
    }
</style>
<body>
    <div class="item" id="box1"></div>
    <div class="item" id="box2"></div>
</body>
閉じていない区間に沿って配置されたボックスの例
閉じていない区間に沿って配置されたボックスの例
この例は、閉じた区間に沿って配置されたボックスを示しています。
<style>
    .item {
        width: 100px;
        height: 40px;
        offset-position: 0% 0%;
        offset-path: path('m 0 0 h 200 v 150 z');
    }
    #box1 {
        background-color: red;
        offset-distance: -280%;
    }
    #box2 {
        background-color: green;
        offset-distance: 190%;
    }
</style>
<body>
    <div class="item" id="box1"></div>
    <div class="item" id="box2"></div>
</body>
閉じた区間に沿って配置されたボックスの例
閉じた区間に沿って配置されたボックスの例
この例では、offset-pathoffset-distance を使って、極座標系内でボックスを揃える方法を示しています。
<style>
    body {
        transform-style: preserve-3d;
        width: 300px;
        height: 300px;
        border: dashed gray;
        border-radius: 50%;
    }
    .circleBox {
        position: absolute;
        left: 50%;
        top: 50%;
        width: 40px;
        height: 40px;
        background-color: red;
        border-radius: 50%;
    }
    #circle1 {
        offset-path: ray(0deg farthest-side);
        offset-distance: 50%;
    }
    #circle2 {
        offset-path: ray(90deg farthest-side);
        offset-distance: 20%;
    }
    #circle3 {
        offset-path: ray(225deg farthest-side);
        offset-distance: 100%;
    }
</style>
<body>
    <div class="circleBox" id="circle1"></div>
    <div class="circleBox" id="circle2"></div>
    <div class="circleBox" id="circle3"></div>
</body>
極座標にボックスを配置した画像
極座標でボックスを配置する例

2.3. パスの開始点: offset-position プロパティ

名前: offset-position
値: normal | auto | <position>
初期値: normal
適用対象: 変形可能な要素
継承: no
パーセンテージ: 包含ブロックのサイズに対して参照
算出値: normal または auto キーワード、もしくは算出された <position>
正規順序: 文法通り
アニメーション型: 算出値ごと
メディア: visual

offset starting position を指定します。これは、<offset-path> 関数が自身の開始位置を指定しない場合に使用されます。

値の定義は以下の通りです:

normal

要素は offset starting position を持ちません。

auto

offset starting position はボックスの左上隅です。

注: これは要素自身のボックスの左上隅であり、 包含ブロック の左上ではありません! top left を指定する場合とは全く異なります。 例えば、path() を要素自身の位置から開始させたい時などを想定しています。

<position>

offset starting position は、 <position> を使ってボックスの 包含ブロック 内に 0x0 のオブジェクト領域を配置して決定されます。

テスト
この例では、offset-position を使ってボックスを配置する方法を示しています。
<style>
    #wrap {
        position: relative;
        width: 300px;
        height: 300px;
        border: 1px solid black;
    }

    #box {
        width: 100px;
        height: 100px;
        background-color: green;
        position: absolute;
        top: 100px;
        left: 80px;
        offset-position: auto;
        offset-anchor: center;
        offset-path: ray(45deg);
    }
</style>
<body>
    <div id="wrap">
        <div id="box"></div>
    </div>
</body>
offset-position: auto の画像
autooffset-position に指定された例
この例は transform プロパティとの相互作用、そして個別の transform プロパティ(rotate)との相互作用を示します。 モーションパス変形は垂直方向の移動であり、(left, top) から offset-position へ移動します。
<style>
#wrap {
    transform-style: preserve-3d;
    width: 400px;
    height: 350px;
}
.item {
    position: absolute;
    left: 200px;
    top: 0px;
    offset-position: 200px 100px; /* 0px,100px だけ移動 */
    offset-anchor: left top;
    transform-origin: left top;
    width: 130px;
    height: 80px;
    border-top-right-radius: 23px;
}
#box1 {
    background-color: tomato;
    offset-position: auto;
}
#box2 {
    background-color: green;
}
#box3 {
    background-color: navy;
    rotate: 90deg; /* モーションパス変形の前に適用 */
}
#box4 {
    background-color: gold;
    transform: rotate(90deg); /* モーションパス変形の後に適用 */
}
</style>
<body>
    <div id="wrap">
        <div class="item" id="box1"></div>
        <div class="item" id="box2"></div>
        <div class="item" id="box3"></div>
        <div class="item" id="box4"></div>
    </div>
</body>
モーションパスと他の transform が相互作用する例
モーションパスと他の transform が相互作用する例
この例では position static を使用しているため、offset-position は標準フロー位置からの移動を生成します。 scale によりこの移動を拡大することで、標準フローが offset-position を中心に180度回転し、ボックスが相互に離れて配置されます。
<style>
#wrap {
    transform-style: preserve-3d;
    width: 500px;
    height: 250px;
    line-height: 0px;
}
span {
    position: static;
    display: inline-block;
    width: 100px;
    height: 50px;
    border-top-right-radius: 23px;
    scale: 2.5 2.5; /* モーションパス変形の前に適用 */
    offset-position: center;
    transform: scale(0.4); /* モーションパス変形の後に適用 */
}
#box1 {
    background-color: tomato;
}
#box2 {
    background-color: green;
}
#box3 {
    background-color: navy;
}
#box4 {
    background-color: gold;
}
</style>
<body>
    <div id="wrap">
        <div>
            <span id="box1"></span><span id="box2"></span>
        </div>
        <div>
            <span id="box3"></span><span id="box4"></span>
        </div>
    </div>
</body>
モーションパスと scale が相互作用する例
モーションパスと scale が相互作用する例
この例では、各 offset-position の値は offset-path<geometry-box> であるため無視されますが、他の offset プロパティが組み合わさることで offset-position 'right bottom' と同等の効果を持ちます。
<style>
#wrap {
    transform-style: preserve-3d;
    width: 540px;
    height: 420px;
}
.item {
    position: absolute;
    width: 90px;
    height: 70px;
    border-top-right-radius: 23px;
    scale: 0.8 0.8; /* モーションパス変形の前に適用 */
    offset-path: padding-box;
    offset-distance: 50%;
    offset-rotate: 0deg;
    offset-anchor: right bottom;
    transform: scale(1.25); /* モーションパス変形の後に適用 */
}
#box1 {
    background-color: tomato;
    position: static;
    offset-position: auto; /* 無視される */
}
#box2 {
    background-color: green;
    right: 0px;
    top: 0px;
    offset-position: 23% 45%; /* 無視される */
}
#box3 {
    background-color: navy;
    left: 0px;
    bottom: 0px;
    offset-position: 34% 56px; /* 無視される */
}
#box4 {
    background-color: gold;
    right: 0px;
    bottom: 0px;
    offset-position: 45px 67px; /* 無視される */
}
</style>
<body>
    <div id="wrap">
        <div class="item" id="box1"></div>
        <div class="item" id="box2"></div>
        <div class="item" id="box3"></div>
        <div class="item" id="box4"></div>
    </div>
</body>
offset-position が無視される例
offset-position が無視される例

2.4. 要素のアンカーポイント: offset-anchor プロパティ

名前: offset-anchor
値: auto | <position>
初期値: auto
適用対象: 変形可能な要素
継承: no
パーセンテージ: 要素の reference box の幅と高さに対する相対値
算出値: auto キーワードまたは算出された <position>
標準順序: 文法に従う
アニメーション型: 算出値による
メディア: visual

要素の offset anchor pointoffset positionoffset path 上で揃える点を定義します。

値の意味は以下の通りです:

auto

アンカーポイントtransform-origin で示される点と同じです。

具体的には、算出値transform-origin は、要素の <position> として reference box に対して解決されます。

<position>

アンカーポイントは、 <position> を要素の reference box に対して解決した結果となります。

テスト

どのボックスが基準になるかは Issue 503 で議論されています。

以下はボックスのアンカーポイントの設定方法を説明します。
#plane {
    offset-anchor: center;
}

図形の中央にある赤い点が、その図形のアンカーポイントを示しています。

アンカーポイント付き図形
飛行機型の中央の赤い点は、その図形のアンカーポイントを表します。
この例は、異なるアンカーポイントを持つ4つのボックスの整列を示します。
<style>
body {
    transform-style: preserve-3d;
    width: 300px;
    height: 300px;
    border: 2px solid gray;
    border-radius: 50%;
}
.box {
    width: 50px;
    height: 50px;
    background-color: orange;
    offset-position: 50% 50%;
    offset-distance: 100%;
    offset-rotate: 0deg;
}
#item1 {
    offset-path: ray(45deg closest-side);
    offset-anchor: right top;
}
#item2 {
    offset-path: ray(135deg closest-side);
    offset-anchor: right bottom;
}
#item3 {
    offset-path: ray(225deg closest-side);
    offset-anchor: left bottom;
}
#item4 {
    offset-path: ray(315deg closest-side);
    offset-anchor: left top;
}
</style>
<body>
    <div class="box" id="item1"></div>
    <div class="box" id="item2"></div>
    <div class="box" id="item3"></div>
    <div class="box" id="item4"></div>
</body>
offset-anchorの例
offset-anchor の例
この例は、ボックスがそれぞれのoffset-positionの中心に配置されることを示します。
<style>
body {
    width: 500px;
    height: 500px;
}
.box {
    background-color: mediumpurple;
    offset-path: none;
    offset-anchor: center;
}
#item1 {
    offset-position: 90% 20%;
    width: 60%;
    height: 20%;
}
#item2 {
    offset-position: 100% 100%;
    width: 30%;
    height: 10%;
}
#item3 {
    offset-position: 50% 100%;
    width: 20%;
    height: 60%;
}
#item4 {
    offset-position: 0% 100%;
    width: 30%;
    height: 90%;
}
</style>
<body>
    <div class="box" id="item1"></div>
    <div class="box" id="item2"></div>
    <div class="box" id="item3"></div>
    <div class="box" id="item4"></div>
</body>
offset-anchor: center の例
'offset-anchor: center' の例
この例は offset-anchor が offset-position にどのように算出されるかを示します。
<style>
body {
    width: 500px;
    height: 500px;
}
.box {
    background-color: mediumpurple;
    offset-path: none;
    offset-anchor: auto;
}
#item1 {
    offset-position: 90% 20%;
    width: 60%;
    height: 20%;
}
#item2 {
    offset-position: 100% 100%;
    width: 30%;
    height: 10%;
}
#item3 {
    offset-position: 50% 100%;
    width: 20%;
    height: 60%;
}
#item4 {
    offset-position: 0% 100%;
    width: 30%;
    height: 90%;
}
</style>
<body>
    <div class="box" id="item1"></div>
    <div class="box" id="item2"></div>
    <div class="box" id="item3"></div>
    <div class="box" id="item4"></div>
</body>
offset-anchor: auto の例
'offset-anchor: auto' の例

2.5. パスに合わせて回転する: offset-rotate プロパティ

名前: offset-rotate
値: [ auto | reverse ] || <angle>
初期値: auto
適用対象: 変形可能な要素
継承: no
パーセンテージ: 該当なし
算出値: 算出された<angle>値、必要に応じてautoが前置される
標準順序: 文法に従う
アニメーション型: 算出値による
メディア: visual

offset transform の回転成分を定義します。 offset path の方向に基づく場合もあり、 offset position 上での方向に依存します。 各値の意味は以下の通りです:

auto <angle>?

offset transform の回転成分は、 offset pathoffset position における方向と、 正のX軸(つまり右向きの線)の方向との差分となります。 SVG のパスの方向の計算方法も参照してください。

角度を指定した場合、その角度が回転成分に加算されます。

注: つまり offset path が右方向の場合、 auto は回転を加えません。 右からずれていくと、その回転量が増えます。 auto に角度を指定することで 「開始時の回転」を調整できます。

reverse <angle>?

auto と同じですが、 回転に 180deg を追加します。

<angle>

単独で指定した場合、 offset transform に指定した角度分の回転成分を加えます。 (つまり、offset-rotate: 45deg;transform: rotate(45deg) と似ていますが、 offset transform の一部として順序付けされます。)

テスト
以下の例では、平面の形状を使用しています。形状の中央にある赤い点は、形状のアンカーポイントを示します。オフセットプロパティが設定されていない場合、形状はパスに沿って移動や回転はされません。
Path without offset
パスの開始位置にある黒い平面で、オフセットプロパティが設定されていません。

形状のアンカーポイントがパス上の異なる位置に配置され、offset-rotate0degの場合、形状は回転しません。

Path without rotation
青色の点線のパス上の異なる位置にある黒い平面で、回転変形はありません。

offset-rotateプロパティがautoに設定されていて、形状のアンカーポイントがパス上の異なる位置に配置されている場合、形状は現在位置のグラデーションに基づいて回転し、その位置のパスの方向を向きます。

Path with auto rotation
青色の点線のパス上の異なる位置にある黒い平面で、パスの方向に回転しています。

この例では、offset-rotateプロパティがreverseに設定されています。平面はパスの各位置でパスの反対方向を向きます。

Path with reverse auto rotation
青色の点線のパス上の異なる位置にある黒い平面で、パスの反対方向に回転しています。

最後の例では、offset-rotateプロパティが-45degに設定されています。形状は45度反時計回りに一度回転し、パス上の各位置でもその回転が維持されます。

Path with fixed rotation
青色の点線のパス上の異なる位置にある黒い平面で、一定の度数だけ回転しています。
この例では、autoまたはreverseを、<angle>と組み合わせて指定した場合の動作を示します。 <angle>の算出値が、autoまたはreverseの算出値に加算されます。
<style>
body {
    width: 300px;
    height: 300px;
    margin: 0px;
    border: solid gray;
    border-radius: 50%;
}
.circle {
    offset-position: 150px 150px;
    offset-distance: 86%;
    width: 42px;
    height: 42px;
    background-color: mediumpurple;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}
#item1 {
    offset-path: ray(0deg closest-side);
    offset-rotate: auto 90deg;
}
#item2 {
    offset-path: ray(45deg closest-side);
    offset-rotate: auto 90deg;
}
#item3 {
    offset-path: ray(135deg closest-side);
    offset-rotate: auto -90deg;
}
#item4 {
    offset-path: ray(180deg closest-side);
    offset-rotate: auto -90deg;
}
#item5 {
    offset-path: ray(225deg closest-side);
    offset-rotate: reverse 90deg;
}
#item6 {
    offset-path: ray(-45deg closest-side);
    offset-rotate: reverse -90deg;
}
</style>
<body>
<div class="circle" id="item1">1</div>
<div class="circle" id="item2">2</div>
<div class="circle" id="item3">3</div>
<div class="circle" id="item4">4</div>
<div class="circle" id="item5">5</div>
<div class="circle" id="item6">6</div>
</body>
An image of example for offset-rotate
ボックスはautoの値に固定の度数が加算されて回転しています。

2.6. offsetのショートハンド

名前: offset
値: [ <'offset-position'>? [ <'offset-path'> [ <'offset-distance'> || <'offset-rotate'> ]? ]? ]! [ / <'offset-anchor'> ]?
初期値: 個々のプロパティを参照
適用対象: 変形可能な要素
継承: 個々のプロパティを参照
パーセンテージ: 個々のプロパティを参照
算出値: 個々のプロパティを参照
アニメーション型: 個々のプロパティを参照
標準的な順序: 構文に従う
テスト

これは、offset-positionoffset-pathoffset-distanceoffset-rotateoffset-anchorを設定するためのショートハンドプロパティです。省略された値は初期値に設定されます。

2.7. オフセット変形の計算

offset transformは、2次元変形であり、平行移動の後に回転が行われます:

3. <basic-shape>用の等価なパス

<basic-shape>の定義は、[css-shapes] にて各関数が 形状 ― 輪郭、内部、外部を持つ2次元の図形 ― を生成するものと定義されています。

この仕様では、<basic-shape>を、特定の形状の輪郭をなぞる線—始点、終点、方向を持つパスとして扱います。 パスの詳細はSVGによって定義されます。[SVG2]

すべての<basic-shape>値の等価なパスは以下の通りです:

<path()>
<shape()>

パスは定義されたパスです。[SVG11]

<circle()>
<ellipse()>

パスは円/楕円の輪郭です。 パスは円/楕円の最も右の点から始まり、 4つの円弧(各々が円/楕円の4分の1)で構成され、 時計回りに進み、 segment-completing close path操作で終わります。

rect()
inset()
xywh()

パスは(角が丸い場合も含む)長方形の輪郭で構成され、 4または8つのセグメント(角が丸いかどうかにより異なる)で構成され、 segment-completing close path操作で終わります。 パスの開始は上辺の左端(角が丸い場合はすぐ右)から始まり、 右方向(時計回り)に進みます。

<polygon()>

パスは多角形の輪郭で、 各座標ペアを次の座標ペアに直線で接続し、 最後は最初の座標に戻り、 segment-completing close path操作で終わります。

これらすべてにおいて、 パス上の任意の点での方向はSVGによって定義されます。 SVG 2 § 9.4 Path directionalityを参照してください。

注: これらはすべて、SVGのshape elementsの「等価なパス」に一致することを意図しています。

注: このリストは、<basic-shape>関数の完全なセットと同期している必要があります。 もし何かが欠けている場合、 それは仕様バグとみなされるべきです。 このリストは将来的にShapesに移動する可能性がありますが、 現時点ではこの仕様のみがこの情報を使用するため、ここに保持されています。

4. プライバシーに関する考慮事項

この仕様では新たなプライバシーに関する考慮事項は導入されません。

5. セキュリティに関する考慮事項

この仕様では新たなセキュリティに関する考慮事項は導入されません。

変更履歴

この節は規範的ではありません。

2018年12月18日作業草案以降の変更点

2015年4月9日最初の公開作業草案以降の変更点

謝辞

fantasai、 Hyojin Song、 その他CSS WGメンバー全員に レビュー、コメント、修正に感謝します。

適合性

文書の規約

適合性要件は、記述的な主張とRFC 2119の用語の組み合わせで表現されます。重要な語句「MUST」「MUST NOT」「REQUIRED」「SHALL」「SHALL NOT」「SHOULD」「SHOULD NOT」「RECOMMENDED」「MAY」「OPTIONAL」は、本仕様書の規範的な部分においてRFC 2119で説明されている通りに解釈されます。 ただし、可読性のため、これらの語句は本仕様書ではすべて大文字では表記されていません。

本仕様のテキストは、明示的に非規範的と記載されたセクション、例、および注記を除き、すべて規範的です。[RFC2119]

本仕様書の例は「例えば」などの語句と共に導入されるか、class="example"で規範的なテキストと区別されて示されます。例:

これは参考例の一例です。

参考注記は「注」と始まり、class="note"で規範的なテキストと区別されて示されます。例:

注:これは参考注記です。

勧告は、特別な注意を促すために規範的なセクションとしてスタイルされ、他の規範的なテキストと区別して<strong class="advisement">で示されます。例: UAはアクセシブルな代替手段を提供しなければなりません。

テスト

本仕様書の内容に関連するテストは、このような「テスト」ブロックに記載される場合があります。 このようなブロックはすべて非規範的です。


適合クラス

本仕様への適合性は、次の3つの適合クラスについて定義されます:

スタイルシート
CSS スタイルシート
レンダラー
UAで、スタイルシートのセマンティクスを解釈し、 それらを用いた文書をレンダリングします。
オーサリングツール
UAで、スタイルシートを作成します。

スタイルシートは、本モジュールで定義される構文を用いたすべての記述が、汎用CSS文法および本モジュールで定義される各機能の個別文法に従って有効であれば、本仕様に適合します。

レンダラーは、スタイルシートを適切な仕様で定義された通りに解釈することに加え、本仕様で定義されたすべての機能を正しく解析し、文書をそれに応じてレンダリングすることで、本仕様に適合します。ただし、UAがデバイスの制限により文書を正しくレンダリングできない場合でも、UAが非適合となるわけではありません。(例えば、UAがモノクロモニターで色のレンダリングを要求されない場合など)

オーサリングツールは、汎用CSS文法および本モジュールの各機能に関する個別文法に従って文法的に正しいスタイルシートを書き、本モジュールで記載されたスタイルシートのその他の適合要件も満たす場合、本仕様に適合します。

部分的な実装

著者がフォワードコンパチブルな解析規則を利用してフォールバック値を指定できるようにするため、CSSレンダラーは、利用可能なサポートレベルがないatルール、プロパティ、プロパティ値、キーワード、その他の構文構造を無効として(適切に無視)扱う必要があります。特に、ユーザーエージェントは、サポートされていない値のみを選択的に無視し、サポートされている値のみを単一の複数値プロパティ宣言で適用してはなりません:いずれかの値が無効と見なされる場合(サポートされていない値は必ず無効になる)、CSSでは宣言全体が無視されます。

不安定および独自機能の実装

将来の安定したCSS機能との衝突を避けるため、CSSWGはベストプラクティスに従い、不安定な機能や独自拡張のCSS実装を推奨します。

非実験的な実装

仕様がCandidate Recommendation段階に達した場合、非実験的な実装が可能となり、実装者は仕様通り正しく実装されたと証明できるCRレベルの機能については、プレフィックスなしの実装をリリースすべきです。

CSSの実装間で互換性を確立し維持するため、CSSワーキンググループは非実験的なCSSレンダラーが、CSS機能のプレフィックスなし実装をリリースする前に、実装報告書(必要に応じてそのためのテストケースも)をW3Cへ提出するよう要請します。W3Cへ提出されたテストケースはCSSワーキンググループによるレビューおよび修正の対象となります。

テストケースおよび実装報告書の提出に関する詳細は、CSSワーキンググループのウェブサイトhttps://www.w3.org/Style/CSS/Test/で確認できます。 質問はpublic-css-testsuite@w3.org メーリングリストへお問い合わせください。

索引

本仕様で定義されている用語

参照により定義される用語

参考文献

規範的参考文献

[CSS-BACKGROUNDS-3]
Elika Etemad; Brad Kemper. CSS Backgrounds and Borders Module Level 3. 2024年3月11日. CR. URL: https://www.w3.org/TR/css-backgrounds-3/
[CSS-BOX-3]
Elika Etemad. CSS Box Model Module Level 3. 2024年4月11日. REC. URL: https://www.w3.org/TR/css-box-3/
[CSS-BOX-4]
Elika Etemad. CSS Box Model Module Level 4. 2024年8月4日. WD. URL: https://www.w3.org/TR/css-box-4/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 2022年1月13日. CR. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-CONTAIN-2]
Tab Atkins Jr.; Florian Rivoal; Vladimir Levin. CSS Containment Module Level 2. 2022年9月17日. WD. URL: https://www.w3.org/TR/css-contain-2/
[CSS-DISPLAY-3]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 3. 2023年3月30日. CR. URL: https://www.w3.org/TR/css-display-3/
[CSS-IMAGES-4]
Tab Atkins Jr.; Elika Etemad; Lea Verou. CSS Images Module Level 4. 2023年2月17日. WD. URL: https://www.w3.org/TR/css-images-4/
[CSS-SHAPES]
Rossen Atanassov; Alan Stearns. CSS Shapes Module Level 1. 2022年11月15日. CR. URL: https://www.w3.org/TR/css-shapes-1/
[CSS-SHAPES-2]
CSS Shapes Module Level 2. 編集者草稿. URL: https://drafts.csswg.org/css-shapes-2/
[CSS-TRANSFORMS-1]
Simon Fraser; et al. CSS Transforms Module Level 1. 2019年2月14日. CR. URL: https://www.w3.org/TR/css-transforms-1/
[CSS-TRANSFORMS-2]
Tab Atkins Jr.; et al. CSS Transforms Module Level 2. 2021年11月9日. WD. URL: https://www.w3.org/TR/css-transforms-2/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2024年3月12日. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-VALUES-5]
Tab Atkins Jr.; Elika Etemad; Miriam Suzanne. CSS Values and Units Module Level 5. 2024年9月17日. WD. URL: https://www.w3.org/TR/css-values-5/
[CSS21]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 2011年6月7日. REC. URL: https://www.w3.org/TR/CSS21/
[CSS3VAL]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. 2024年3月22日. CR. URL: https://www.w3.org/TR/css-values-3/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997年3月. ベストカレントプラクティス. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SVG11]
Erik Dahlström; et al. Scalable Vector Graphics (SVG) 1.1 (Second Edition). 2011年8月16日. REC. URL: https://www.w3.org/TR/SVG11/
[SVG2]
Amelia Bellamy-Royds; et al. Scalable Vector Graphics (SVG) 2. 2018年10月4日. CR. URL: https://www.w3.org/TR/SVG2/

参考情報

[CSS-MASKING-1]
Dirk Schulze; Brian Birtles; Tab Atkins Jr.. CSS Masking Module Level 1. 2021年8月5日. CR. URL: https://www.w3.org/TR/css-masking-1/
[CSS-POSITION-3]
Elika Etemad; Tab Atkins Jr.. CSS Positioned Layout Module Level 3. 2024年8月10日. WD. URL: https://www.w3.org/TR/css-position-3/
[CSS-ROUND-DISPLAY-1]
Jihye Hong. CSS Round Display Level 1. 2016年12月22日. WD. URL: https://www.w3.org/TR/css-round-display-1/
[MOTION-1]
Dirk Schulze; et al. Motion Path Module Level 1. 2018年12月18日. WD. URL: https://www.w3.org/TR/motion-1/

プロパティ索引

名前 初期値 適用対象 継承 パーセンテージ アニメーション型 標準的な順序 算出値 メディア
offset [ <'offset-position'>? [ <'offset-path'> [ <'offset-distance'> || <'offset-rotate'> ]? ]? ]! [ / <'offset-anchor'> ]? 個々のプロパティを参照 変形可能な要素 個々のプロパティを参照 個々のプロパティを参照 個々のプロパティを参照 構文に従う 個々のプロパティを参照
offset-anchor auto | <position> auto 変形可能な要素 いいえ 要素の参照ボックスの幅と高さに対して相対的 算出値による 構文に従う autoキーワードまたは算出された<position> 視覚
offset-distance <length-percentage> 0 変形可能な要素 いいえ offset pathの長さに対して相対的 算出値による 構文に従う 算出された<length-percentage>値 視覚
offset-path none | <offset-path> || <coord-box> none 変形可能な要素 いいえ 該当なし 算出値による 構文に従う 指定通り 視覚
offset-position normal | auto | <position> normal 変形可能な要素 いいえ 包含ブロックのサイズを参照 算出値による 構文に従う normalまたはautoキーワード、または算出された<position> 視覚
offset-rotate [ auto | reverse ] || <angle> auto 変形可能な要素 いいえ 該当なし 算出値による 構文に従う 算出された<angle>値(autoが先頭につく場合あり) 視覚

課題索引

これらの例はすべて書き直す必要があります。
どのボックスが解決対象になるかは Issue 503 で議論されています。