CSSパララックス効果 実践ガイド ―
スクロールに奥行きを与える3つの手法

background-attachment、perspective transform、scroll-driven animations。同じ「パララックス」でもアプローチはまるで違います。それぞれの仕組みと使い分けを、動くデモで確認しましょう。

パララックスとは何か ― 目の錯覚から生まれるUI効果

電車の窓から外を眺めたとき、近くの電柱は猛スピードで流れていくのに、遠くの山はほとんど動かない。この「近いものほど速く、遠いものほど遅く動く」現象を視差効果(パララックス)と呼びます。

Webデザインにおけるパララックスは、この視差を画面上で再現すること。スクロールに連動して、背景と前景を異なる速度で動かすだけで、平面だったページに奥行きと立体感が生まれます。

ただし、実装方法は一つではありません。大きく分けて3つのアプローチがあり、それぞれに得手不得手があります。現場で「なんとなくやってみたけどカクカクする」「モバイルで動かない」という問題に直面したことがあるなら、この記事はきっと役に立つはずです。

手法1: background-attachment: fixed ― 最もシンプルな入口

パララックスの入門として最も手軽なのが、CSSの background-attachment: fixed を使う方法です。背景画像をビューポートに固定し、コンテンツだけがスクロールすることで、背景が「ゆっくり動いているように」見える。実際には背景は動いていないのですが、相対的な速度差が視差効果を生みます。

background-attachment: fixed の基本
.parallax-section {
  min-height: 400px;
  background-image: url('hero.webp');
  background-attachment: fixed;
  background-position: center;
  background-size: cover;
}
▶ Live Demo — background-attachment: fixed
↕ スクロールしてください

この白いコンテンツ部分はスクロールしますが、上のグラデーション背景はビューポートに固定されています。コンテンツが上に流れていくにつれて、背景が「覗き窓」のように見えるのがポイントです。

background-attachment: fixed は、最も少ないコード量でパララックス風の効果を得られる方法です。画像を使えば、スクロールとともに風景が現れるような演出ができます。

ただし、この手法にはモバイルブラウザで動作しないという大きな制約があります。iOSのSafariやAndroidのChromeでは、パフォーマンス上の理由から background-attachment: fixed が無視されます。

デスクトップ限定の演出と割り切るか、モバイルではフォールバックを用意する必要があります。次のセクションで、モバイルでも動く手法を見ていきましょう。

背景は固定されたまま

再びコンテンツ領域です。スクロールを続けると、また固定背景が現れます。セクション間の区切りとして使うのが定番のパターンです。

⚠️ 注意
background-attachment: fixed はiOS Safari・Android Chrome で無視されます。モバイルでは背景が通常スクロールになるだけで壊れはしませんが、パララックス効果は得られません。モバイル対応が必須の案件では、次に紹介する perspective 手法か scroll-driven animations を検討してください。
❌ やりがちなNG: scroll イベントで background-position を動かす
/* パフォーマンスが悪い。メインスレッドを毎フレーム占有する */
window.addEventListener('scroll', () => {
  element.style.backgroundPosition =
    `center ${window.scrollY * 0.5}px`;
});
✅ CSSだけで完結させる
.parallax-section {
  background-attachment: fixed;
  /* JS不要。ブラウザが最適化してくれる */
}

手法2: perspective + translateZ ― 本物の3D視差

CSS の 3D Transform を使えば、ブラウザの描画エンジンに「奥行き」を計算させることができます。これが最も「本物のパララックス」に近い手法です。

仕組みはこうです。親要素に perspective を設定して「カメラからの距離」を定義し、子要素を translateZ() で手前や奥に配置する。奥にある要素ほどスクロール時の移動量が小さくなり、自然な視差が生まれます。

perspective + translateZ の構造
.parallax-container {
  height: 100vh;
  overflow-x: hidden;
  overflow-y: auto;
  perspective: 1px;
  perspective-origin: center;
}

.parallax-layer--back {
  transform: translateZ(-2px) scale(3);
  /* 奥に配置 → スクロールが遅く見える */
  /* scale で縮小を補正 */
}

.parallax-layer--front {
  transform: translateZ(0);
  /* 通常の位置 → 通常速度でスクロール */
}

ポイントは scale() による補正です。translateZ(-2px) で奥に下げると要素は遠ざかって小さく見えるので、scale(3) で拡大して元のサイズに戻す。この計算は 1 + (translateZの絶対値 / perspective) で求められます(perspective: 1px、translateZ: -2px の場合、1 + 2/1 = 3)。

▶ Live Demo — perspective パララックス(3レイヤー)
⛰️ ⛰️ ⛰️

前景コンテンツ

このカードは translateZ(0) で最前面にあります。スクロールすると、背景のグラデーションと中景の山はゆっくり動き、このカードは通常速度で動きます。

💡 現場の経験則
perspective 手法は「本物の3D」なので視差の自然さは抜群ですが、transform-style: preserve-3doverflow の相性が悪く、レイアウトが複雑になるとハマりがちです。全画面ヒーローセクションのように、限定された領域で使うのがコツです。

手法3: scroll-driven animations ― これからの本命

2024年以降、CSSに animation-timeline というプロパティが追加されました。これはアニメーションの進行を「時間」ではなく「スクロール位置」に紐づけるもの。この機能を使えば、JavaScriptなしでスクロール連動のパララックスが書けます。

scroll-driven animations によるパララックス
.parallax-bg {
  animation: parallax-shift linear both;
  animation-timeline: scroll();
  animation-range: 0% 100%;
}

@keyframes parallax-shift {
  from { transform: translateY(0); }
  to   { transform: translateY(-100px); }
}

animation-timeline: scroll() がキモです。これを指定すると、アニメーションの0% → 100%が、スクロール位置の先頭 → 末尾にマッピングされます。背景要素に「スクロールの50%の速度で動く」ような translateY を設定すれば、それがそのままパララックスになります。

▶ Live Demo — scroll-driven animations パララックス
↕ スクロールすると背景テキストが変化

scroll-driven animations は、スクロール位置をアニメーションのタイムラインとして使う新しいCSS機能です。この例では、背景のテキストがスクロールに応じて上に移動し、縮小し、フェードアウトしていきます。

従来の JavaScript による scroll イベントリスナーとは違い、ブラウザのコンポジター層で処理されるため、60fps のスムーズな動きが保証されます。メインスレッドをブロックしません。

この手法の最大のメリットは「CSS完結」であること。JavaScript を一行も書かずに、スクロール連動のアニメーションが実現できます。パフォーマンスも優秀です。

ただし、2025年時点では Chrome と Edge でフルサポート、Firefox は一部対応、Safari は未対応という状況です。プログレッシブ・エンハンスメント(動かなくても壊れないように作る)が前提になります。

スクロールを続けて、背景の変化を観察してください。

📌 ポイント
scroll-driven animations は @supports (animation-timeline: scroll()) で機能検出できます。対応ブラウザではリッチなパララックスを、非対応ブラウザでは静的なレイアウトをフォールバックとして表示する——これがプログレッシブ・エンハンスメントの考え方です。

3つの手法を比較する ― どれを選ぶべきか

▶ Live Demo — 要素ごとに異なる速度で動くパララックスレイヤー
各円が異なる速度で動きます
↕ スクロール

上のデモは scroll-driven animations を使い、4つの円それぞれに異なる translateY 量を設定しています。近くにある小さな円はゆっくり、大きな円は速く——これだけで奥行きの錯覚が生まれます。

では、3つの手法をどう使い分ければいいのか。判断基準をまとめます。

background-attachment: fixed は、コード量最小で背景画像に視差を付けたいとき。デスクトップ限定と割り切れるなら最も簡単です。perspective + translateZ は、複数レイヤーを3D空間に配置して「本物の」パララックスを作りたいとき。ヒーローセクションなど限定領域向きです。scroll-driven animations は、要素ごとに細かく速度をコントロールしたいとき。これからのスタンダードになる手法ですが、現時点ではブラウザサポートに注意が必要です。

✅ プログレッシブ・エンハンスメントの実装例
/* ベース: パララックスなし(すべてのブラウザで動く) */
.hero-bg {
  background: url('bg.webp') center / cover;
}

/* scroll-driven animations 対応ブラウザのみ */
@supports (animation-timeline: scroll()) {
  .hero-bg {
    animation: parallax linear both;
    animation-timeline: scroll();
  }
}

パフォーマンスとアクセシビリティ

パララックスは華やかな反面、2つの落とし穴があります。

一つ目はパフォーマンス。JavaScriptの scroll イベントで毎フレーム style を書き換える方法は、メインスレッドを占有してカクつきの原因になります。CSS完結の手法(background-attachmentperspectivescroll-driven animations)はコンポジターレイヤーで処理されるため、60fpsを維持しやすい。どうしてもJSが必要な場合は IntersectionObserver で「見えている範囲だけ」処理するのが鉄則です。

二つ目はアクセシビリティ。パララックスの動きは前庭障害のあるユーザーにめまいや吐き気を引き起こすことがあります。必ず prefers-reduced-motion に対応しましょう。

prefers-reduced-motion 対応
@media (prefers-reduced-motion: reduce) {
  .parallax-bg {
    animation: none;
    background-attachment: scroll;
    transform: none;
  }
}

まとめ

  • パララックス(視差効果)は、背景と前景を異なる速度で動かすことで奥行きを演出するUI手法である
  • background-attachment: fixed は最も手軽だが、モバイルブラウザでは動作しない制約がある
  • perspective + translateZ はCSS 3D Transformを活用した「本物の」視差効果で、scale() による補正が必要
  • scroll-driven animations は CSS の animation-timeline: scroll() を使い、スクロール位置でアニメーションを制御する次世代手法
  • JavaScript の scroll イベントリスナーは避け、CSS完結の手法を選ぶほうがパフォーマンスに優れる
  • 前庭障害のあるユーザーに配慮し、prefers-reduced-motion でパララックスを無効化するコードを必ず書く
  • scroll-driven animations のブラウザサポートは発展途上のため、@supports でプログレッシブ・エンハンスメントを実践する