CSSとレイアウトアニメーションアクセシビリティ

スクロールアニメーション:IntersectionObserverの代わりにanimation-timeline

スクロールアニメーション:IntersectionObserverの代わりにanimation-timeline

Scroll-driven animationsは問題を根本から断ち切ります。それはあなたがすでに知っているCSSアニメーションと同じで、一つの置き換えだけが違います:時間が進行を駆動する代わりに、スクロールコンテナの位置がそれを行います。ブラウザはコンポジターで実行できます。

4行の進行バー

css

.progress {
position: fixed;
inset: 0 0 auto 0;
height: 4px;
transform-origin: left;
animation: grow linear both;
animation-timeline: scroll(root block);
}
@keyframes grow {
from { transform: scaleX(0); }
to { transform: scaleX(1); }
}

スクロール時の表示:view()タイムライン

css

.reveal {
animation: fade-up linear both;
animation-timeline: view();
animation-range: entry 0% entry 60%;
}
@keyframes fade-up {
from { opacity: 0; transform: translateY(32px); }
to { opacity: 1; transform: translateY(0); }
}

4つの名前付き範囲:entry、exit、cover(デフォルト)、contain。

1時間を無駄にする落とし穴:animationショートハンドがタイムラインをリセットする

css

/* 壊れている:ショートハンドがanimation-timelineをautoにリセット */
.reveal {
animation-timeline: view();
animation-range: entry 0% entry 60%;
animation: fade-up linear both;
}

css

/* 正しい:ショートハンドの後にタイムラインと範囲 */
.reveal {
animation: fade-up linear both;
animation-timeline: view();
animation-range: entry 0% entry 60%;
}

名前付きタイムライン

css

.gallery {
overflow-x: auto;
scroll-timeline: --gallery inline;
}
.gallery-indicator {
animation: fill linear both;
animation-timeline: --gallery;
timeline-scope: --gallery;
}

プログレッシブエンhancementはここでは任意ではない

css

.reveal {
opacity: 1;
}
@supports (animation-timeline: view()) {
@media (prefers-reduced-motion: no-preference) {
.reveal {
animation: fade-up linear both;
animation-timeline: view();
animation-range: entry 0% entry 60%;
}
}
}

落とし穴とベストプラクティス

  • transformとopacityだけをアニメーションする。
  • アニメーションだけが明らかにできるコンテンツを隠さない。
  • 「なぜアニメーションが止まっているのか?」はほとんどの場合スクロールコンテナの問題。
  • bothをfillモードとして使用する。
  • Reduced motionは医療的な設定であり、礼儀ではない。
  • まだ必要なJavaScriptを削除しない。

まとめ

Scroll-driven animationsはメインスレッドに関する同じアイデアをエフェクトの全カテゴリに適用します:スクロールリスナー、オブザーバー、クラス変更が必要だったものが一つのCSSプロパティになります。