スクロールで要素フェードイン(CSS のみ)
JavaScript なし・Intersection Observer 不要で、要素がビューポートに入ったタイミングに応じてフェードイン演出を実装。animation-range で開始タイミング調整可能。
解説
スクロールで要素フェードイン(CSS のみ)は、アニメーションカテゴリの「scroll-driven」に分類される実装パターンです。CSS のみで構成され、難易度は中級レベル。
animation-timeline: view() は、各要素が「ビューポートに入っている量」をタイムラインとして CSS アニメーションに紐付けられる機能です。Intersection Observer を JavaScript で書くより遥かにシンプルに、よくある「スクロールで要素がフワッと登場」演出を実装できます。
このサンプルでは、複数のカードを下から順番にフェードインさせています。animation-range: entry 0% cover 30% で「要素の上端がビューポートに入った瞬間から、要素の上端が画面中央 30% 地点に来るまで」にアニメーションを完了させる、繊細な制御をしています。
仕組み
下記コードタブから HTML / CSS をそれぞれ確認・コピーできます。プレビュー領域では実際の動作をその場で確認可能です。
CSS プロパティだけで完結しているため、フレームワーク非依存・軽量に組み込めます。React / Vue / Astro / 静的 HTML どれにも持ち込み可能です。
注意点 / カスタマイズ時のポイント
Chrome / Edge / Opera 対応。Safari / Firefox は未対応のため、フォールバック実装が必要な場合は Intersection Observer の JS 版を併用してください。
animation-range の entry / cover / exit の使い分けは慣れが必要です。entry = 要素がビューに入る瞬間、cover = ビュー内を移動中、exit = 出ていく瞬間と覚えるとよいです。
よくある質問
1 度だけ再生して、戻ったら再アニメーションさせたくない
animation-fill-mode: forwards + 1 回再生後にクラスを付与する JS が必要です。Safari でフォールバック実装したい
@supports not (animation-timeline: view()) で分岐し、Intersection Observer で is-in クラスを付ける処理を書いてください。このスニペットは商用利用できますか?
そのまま貼り付ければ動きますか?
ブラウザ対応は?
Tailwind CSS でも実装できますか?
@apply や arbitrary values が必要な場合があります。