いま、このサイトは JavaScript でやっている
Terralien の共通レイアウトには IntersectionObserver が入っていて、セクションが画面に入ったら class を付けてフェードインさせています。20 行ほどのスクリプトです。
このサイトが今 IntersectionObserver でやっている処理を、CSS の animation-timeline で置き換えられるか。
ページ最上部の細いバーが、スクロール量に合わせて伸びます。画面を上下させると、そのまま追従します。
@supports (animation-timeline: scroll()) {
.sda-progress span {
transform-origin: 0 50%;
animation: sda-grow linear both;
animation-timeline: scroll(root block);
}
}
@keyframes sda-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } } 下の 4 枚は、画面に入った量そのものが進行度になっています。ゆっくりスクロールすると、途中で止められます。
Terralien の共通レイアウトには IntersectionObserver が入っていて、セクションが画面に入ったら class を付けてフェードインさせています。20 行ほどのスクリプトです。
animation-timeline: view() を使うと、要素が画面に入った量そのものをアニメーションの進行度にできます。「入ったら再生」ではなく「入った分だけ進む」なので、スクロールを戻すとアニメーションも戻ります。
JavaScript 版は一度発火したら戻りません(observe を解除しているため)。この違いは好みの問題ではなく、設計の違いです。どちらが良いかは中身によります。
@supports で囲ってあるので、対応していないブラウザにはアニメーションの指定そのものが届きません。テキストは最初から見えています。「透明のまま出てこない」という最悪の壊れ方をしないための書き方です。
@supports (animation-timeline: view()) {
.sda-card {
animation: sda-rise linear both;
animation-timeline: view();
animation-range: entry 5% cover 30%;
}
}
@keyframes sda-rise {
from { opacity: 0; transform: translateY(24px); }
to { opacity: 1; transform: none; }
} | 観点 | CSS(今回) | IntersectionObserver(現行) |
|---|---|---|
| 追加する JS | 0 行 | 約 20 行(共通レイアウトに常駐) |
| スクロールを戻したとき | アニメーションも戻る | 戻らない(一度きり) |
| 要素の指定 | CSS セレクタ | セレクタ文字列をスクリプト側に持つ |
| 未対応時 | 最初から見えている | 最初から見えている(同じくフォールバック済み) |
| 置き換えの可否 | 現行の「一度きりで止める」挙動を維持したいなら、CSS だけでは同じにならない | |
prefers-reduced-motion: reduce のとき、バーもフェードインも止めています。止めた結果として情報が消えないこと(=最初から全部見えていること)まで含めて確認するのが要件です。
判定を「保留」にした理由: 共通レイアウトのスクリプトを消せるかは、まだ決められません。現行は「一度出たら戻さない」挙動で、本文の読みやすさはそちらのほうが素直です。バーだけ先に採用するのが現実的だと考えています。