CSSだけで作るパララックススクロール
CSSパララックススクロールガイド
CSSだけで作るパララックススクロール:perspectiveとスクロール駆動
CSSのperspectiveとtranslateZ、またはスクロール駆動アニメーションでパララックスを作り、奥行きの計算をその場で確認しながら、スマートフォンや動きを減らす設定にも正しく対応しましょう。
CSSだけのパララックスには、確実な方法が2つあります。perspective方式では、perspectiveを持つスクロールコンテナを作り、背景のレイヤーをtranslateZで奥に押し込み、(perspectiveからzを引いた値)をperspectiveで割った倍率で拡大します。新しい方式では、translateのアニメーションをanimation-timeline: view()に結び付けます。どちらもprefers-reduced-motionのときは無効にすべきです。
パララックス効果を得る3つの方法
- perspective + translateZ
- 3Dのスクロールコンテナ内で、奥のレイヤーほどゆっくりスクロールする
- ページではなく専用のスクロールコンテナが必要
- animation-timeline: view()
- キーフレームのtranslateが、ビューポートを通過する要素に追従する
- Chrome、Edge 115以降、Safari 26以降、Firefox 161以降
- background-attachment: fixed
- コンテンツが上を動く間、背景は止まったまま
- iOS Safariでは部分的な対応。多くのスマホで遅れる
- JavaScriptによる代替
- スクロール位置に応じて毎フレームtransformを設定する
- requestAnimationFrameとpassiveなリスナーを使う
多くのパララックスのチュートリアルはbackground-attachment: fixedで終わっていますが、iPhoneはこれに部分的にしか対応していません。このガイドでは、実際にレイヤーを動かす2つの方法を紹介し、レイヤーが縮まないための拡大率の計算を説明し、小さなスクリプトによる代替と、誰も気分が悪くならないようにするための動きを減らす設定への対応も紹介します。
- プレイグラウンドの奥行きスライダーを動かして、背景のレイヤーをさらに奥へ押し込みます。
- プレビューをスクロールし、奥のレイヤーと手前のテキストの動く速さを比べます。
- 計算された拡大率と速さを確認します。下のCSSで使われているのはこの値です。
- 合う方法をコピーします。限られたヒーロー領域ならperspective、通常のページのセクションならview()です。
- perspective pの下でtranslateZ(z)にあるレイヤーは、スクロール速度のp÷(p−z)の速さで動きます。
- 拡大されたレイヤーは元のボックスより幅が広くなるので、パララックスのコンテナにはoverflow-x: hiddenを指定しましょう。
- animationの一括指定はanimation-timelineをautoにリセットしてしまうので、animation-timelineはその後に宣言しましょう。
- 動きは@media (prefers-reduced-motion: no-preference)で囲み、効果がデフォルトでオプトインになるようにしましょう。
よくある質問
translateZを使ったレイヤーが小さく見えるのはなぜですか?
負のtranslateZで要素を見る人から遠ざけると、遠くの物体とまったく同じように小さくなります。元のサイズに戻すにはscale((p - z) / p)を追加します。perspective: 1pxとtranslateZ(-2px)なら、scale(3)です。
background-attachment: fixedはスマートフォンで動きますか?
確実には動きません。caniuseではiOS Safariは部分的な対応とされ、ほとんどのモバイル端末ではスクロール後に固定背景の更新が遅いと記されています。デスクトップだけのおまけと考え、効果が重要な場合はtransformを使う方法のどちらかを使いましょう。
パララックスはアクセシビリティに悪いですか?
スクロールに連動する大きな動きは、前庭障害のある人にめまいや吐き気を引き起こすことがあります。prefers-reduced-motionメディアクエリでOSの視差効果を減らす設定を尊重し、その設定がオンのときはレイヤーを静止させて表示しましょう。
スクロール駆動のパララックスに対応しているブラウザーは?
2026年10月時点で、caniuseではanimation-timelineはChromeとEdgeが115から、Safariが26から、Firefoxが161から対応しています。古いブラウザーはアニメーションを飛ばすだけなので、効果がなくてもページは正しく読めます。
perspective方式のしくみ
- コンテナがスクロールする要素になり、perspectiveの値を持ちます。子要素はtransform-style: preserve-3dで3D上の位置を保ちます。コンテナがスクロールすると、z方向で奥にあるレイヤーはzが0のレイヤーより画面上の移動距離が短くなるため、遅れてついてくるように見えます。
- 要素にperspectiveを指定すると、スタッキングコンテキストと、固定配置の子要素の包含ブロックも作られるため、パララックスのラッパーは独立させておきましょう。ウィンドウに固定しておく必要があるヘッダーは、その外に置きます。
スマートフォンと古いブラウザー
- 高性能なパララックスについてのChrome自身の解説によると、以前はiOSの慣性スクロールが3Dコンテキストを平らにしてしまい、iPhoneではperspectiveの技が使えませんでした。実機でテストし、レイヤーが動かなくてもコンテンツが読めるようにしておきましょう。
- スクロール駆動の方式はページの通常のスクロールで動くため、このような問題はありません。対応していない環境ではキーフレームが実行されず、レイヤーは静止位置に留まるので、きれいな代替になります。
方法1:perspectiveとtranslateZ
専用のスクロール領域を持つ2層のヒーロー
枠の中をスクロールしてください。縞模様のレイヤーはtranslateZ(-2px)にあり3倍に拡大されているため、スクロール速度の3分の1で動きます。
方法2:view()によるスクロール駆動
セクションが画面を横切るにつれて流れる画像
アニメーションは、animation-timelineに対応していて、読み手が動きを減らす設定にしていない場合にだけ実行されます。
JavaScriptによる代替
requestAnimationFrameを使った小さなパララックス
スクロール駆動アニメーションがない場合にだけ使われます。リスナーはpassiveで、処理は1フレームに1回だけ行われます。
奥行きプレイグラウンド
奥のレイヤーの奥行き(translateZ):{n}px
必要な拡大率:{v}
奥のレイヤーの速さ:スクロールの{v}
パララックスのプレビュー。中をスクロールしてください
手前のテキストは全速力で動きます
スクロールを続けると、奥のレイヤーが遅れてついてくる様子が見られます。
お使いの端末は動きを減らす設定になっているため、プレビューは静止したままです。
CSSをコピー
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る