スクロールに応じたアニメーションは、UIに自然な動きを加える重要なパターンです。
まずは基本的なスクロール連動の考え方から知りたい方は、こちらも参考にしてください。
→ Scroll Progress Animationの作り方
スクロールに合わせて背景や装飾が少しずつズレて動く表現は、ページに奥行きや気持ちよさを加えてくれます。
このような演出は Parallax Scroll Animation と呼ばれ、LPやポートフォリオ、ヒーローセクションなどでよく使われます。
今回は、複雑なライブラリを使わずに、HTML・CSS・JavaScriptだけで作れるシンプルなParallax Scroll Animation を紹介します。
この記事では、次の流れで確認していきます。
- Parallax Scroll Animation とは何か
- どういう仕組みで動くのか
- コピペで使える実装例
- 実装時の注意点
スクロール演出の基本を押さえたい人にちょうどいい内容です。
1.Parallax Scroll Animationとは?
Parallax Scroll Animationは、スクロール量に応じて複数の要素を異なる速度で動かす表現です。
たとえば、次のような構成がよくあります。
- 背景はゆっくり動く
- 手前の装飾は少し速く動く
- テキストはさらに控えめに動く
この速度差によって、平面的なページでも奥行きがあるように見えるのが特徴です。
単純に要素を一緒に動かすだけではなく、
「どの要素を、どのくらいの比率で動かすか」 を分けるのがポイントです。
2.今回の実装方針
今回のサンプルでは、ヒーローエリアの中に複数のレイヤーを置き、スクロール量に応じて translateY() を変化させます。
やることはとてもシンプルです。
- スクロール位置を取得する
- 各レイヤーに速度係数を持たせる
transform: translateY(...)で動かす
この方式なら、構造が分かりやすく、後から調整もしやすいです。
3.完成イメージ
今回作るUIは、以下のような動きをします。
- 背景グラデーションの上に複数の円形レイヤーを配置
- スクロールすると、それぞれが異なる速度で上下にずれる
- 見出しテキストも少しだけ追従して動く
- 下にスクロールすると自然に奥行き感が出る
見た目はシンプルですが、スクロール演出の基本を学ぶには十分です。
HTML
<section class="parallax-hero">
<div class="parallax-bg layer" data-speed="0.15"></div>
<div class="parallax-orb orb-1 layer" data-speed="0.35"></div>
<div class="parallax-orb orb-2 layer" data-speed="0.6"></div>
<div class="parallax-orb orb-3 layer" data-speed="0.25"></div>
<div class="hero-content layer" data-speed="0.2">
<p class="eyebrow">Scroll Motion Pattern</p>
<h1>Parallax Scroll Animation</h1>
<p class="lead">
Different layers move at different speeds to create depth.
</p>
</div>
</section>
<section class="content">
<div class="content-inner">
<h2>Why it feels good</h2>
<p>
Parallax creates a subtle sense of depth with only a small amount of motion.
It works especially well in hero sections, landing pages, and visual storytelling.
</p>
<h2>Implementation</h2>
<p>
In this demo, each layer reads the current scroll position and moves vertically
based on its own speed factor.
</p>
<h2>Tips</h2>
<p>
Keep the effect subtle. If everything moves too much, readability drops and the page
can feel unstable.
</p>
<div class="spacer"></div>
</div>
</section>CSS
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
}
body {
font-family: Arial, sans-serif;
color: #e8ecf1;
background: #0b1020;
line-height: 1.7;
}
.parallax-hero {
position: relative;
min-height: 100vh;
overflow: hidden;
display: grid;
place-items: center;
padding: 24px;
background:
radial-gradient(circle at 20% 20%, rgba(90, 140, 255, 0.28), transparent 30%),
radial-gradient(circle at 80% 30%, rgba(120, 255, 210, 0.18), transparent 28%),
linear-gradient(180deg, #10172d 0%, #0b1020 100%);
}
.parallax-bg {
position: absolute;
inset: -10%;
background:
radial-gradient(circle at 30% 40%, rgba(255, 255, 255, 0.08), transparent 18%),
radial-gradient(circle at 70% 60%, rgba(255, 255, 255, 0.06), transparent 22%);
pointer-events: none;
}
.parallax-orb {
position: absolute;
border-radius: 999px;
filter: blur(4px);
opacity: 0.9;
pointer-events: none;
}
.orb-1 {
width: 220px;
height: 220px;
top: 14%;
left: 10%;
background: linear-gradient(135deg, rgba(123, 92, 255, 0.9), rgba(78, 205, 255, 0.55));
}
.orb-2 {
width: 300px;
height: 300px;
right: 8%;
top: 20%;
background: linear-gradient(135deg, rgba(58, 209, 154, 0.8), rgba(115, 224, 255, 0.35));
}
.orb-3 {
width: 180px;
height: 180px;
left: 22%;
bottom: 10%;
background: linear-gradient(135deg, rgba(255, 120, 180, 0.7), rgba(255, 210, 120, 0.4));
}
.hero-content {
position: relative;
z-index: 2;
width: min(800px, 100%);
text-align: center;
padding: 40px 24px;
border: 1px solid rgba(255, 255, 255, 0.08);
background: rgba(255, 255, 255, 0.05);
backdrop-filter: blur(10px);
border-radius: 24px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.28);
}
.eyebrow {
margin: 0 0 12px;
font-size: 13px;
letter-spacing: 0.12em;
text-transform: uppercase;
color: #8fb4ff;
}
.hero-content h1 {
margin: 0;
font-size: clamp(36px, 7vw, 72px);
line-height: 1.05;
}
.lead {
margin: 18px auto 0;
max-width: 560px;
font-size: 18px;
color: #c8d4e3;
}
.content {
background: #f6f8fb;
color: #1d2433;
}
.content-inner {
width: min(820px, calc(100% - 40px));
margin: 0 auto;
padding: 80px 0 120px;
}
.content h2 {
margin-top: 0;
margin-bottom: 12px;
font-size: 28px;
}
.content p {
margin-top: 0;
margin-bottom: 48px;
color: #4b5568;
}
.spacer {
height: 60vh;
}
@media (prefers-reduced-motion: reduce) {
.layer {
transform: none !important;
}
}JavaScript
<script>
const layers = document.querySelectorAll(".layer");
const updateParallax = () => {
const scrollY = window.scrollY;
layers.forEach((layer) => {
const speed = parseFloat(layer.dataset.speed || 0);
const y = scrollY * speed;
layer.style.transform = `translateY(${y}px)`;
});
};
updateParallax();
window.addEventListener("scroll", updateParallax, { passive: true });
</script>4.まずはそのまま動かしてみる
上のコードをそのまま配置すると、スクロール時に各レイヤーが異なる速度で移動します。
ここで一番大事なのは、この部分です。
const y = scrollY * speed;
layer.style.transform = `translateY(${y}px)`;スクロール量に speed を掛けることで、要素ごとに移動量を変えています。
たとえば、
0.15ならゆっくり動く0.6なら大きく動く
という違いになります。
この差が、Parallaxらしい奥行き感を作ります。
5.data-speed を変えると印象が変わる
HTMLでは各レイヤーに data-speed を付けています。
<div class="parallax-orb orb-1 layer" data-speed="0.35"></div>
<div class="parallax-orb orb-2 layer" data-speed="0.6"></div>
<div class="parallax-orb orb-3 layer" data-speed="0.25"></div>この値を変えるだけで、見た目の印象がかなり変わります。
小さめの値
控えめで上品な動きになります。
読み物系のページや、落ち着いたデザインに向いています。
大きめの値
動きが目立ちやすくなります。
ただし、やりすぎると視線が散りやすくなるので注意が必要です。
最初は 0.1〜0.4くらいを中心に調整 すると扱いやすいです。
6.Parallaxを自然に見せるコツ
Parallax Scroll Animationは、派手にしようとすると逆に使いづらくなります。
自然に見せるには、次のような考え方が大事です。
①テキストは動かしすぎない
見出しや本文を大きく動かすと読みづらくなります。
テキストはごく小さく、背景や装飾のほうを大きめに動かすとバランスが取りやすいです。
②レイヤー数を増やしすぎない
最初から何層も入れると調整が難しくなります。
まずは 背景・装飾・テキスト の3段階くらいで十分です。
③transform を使う
位置変更に top や margin-top を多用すると、レイアウト計算が増えて重くなりやすいです。
こうしたアニメーションでは、基本的に transform を使う のが定番です。
位置の更新に transform を使う理由は、パフォーマンスに大きく影響するためです。
フレームレートや描画負荷については、こちらの記事も参考になります。
→ フレームレートとパフォーマンス
④強すぎる演出にしない
Parallaxは主役ではなく、ページ全体を気持ちよく見せるための補助演出です。
「少し物足りないかも」くらいの強さのほうが、実際にはちょうどよく見えることが多いです。
動きをより自然に見せたい場合は、イージングの考え方も重要になります。
スクロール以外のアニメーションでも使える基本なので、こちらもおすすめです。
→ easing / cubic-bezierの基礎
スクロール系のアニメーションは他にもいくつかパターンがあります。
- 進捗を可視化する
- 要素を順番に表示する
- 位置に応じて発火する
それぞれの違いを知りたい方はこちらもどうぞ。
→ Scroll Progress Animation
→ Scroll Reveal Animation
→ Stagger Animation
7.実験:スクロール量と速度係数で奥行きの見え方を比べてみよう
Parallax Scroll Animationは、同じレイアウトでも速度差の付け方だけで印象が変わります。
このデモでは、スクロール量に応じて複数のレイヤーが異なる速度で動きます。背景・装飾・テキストの速度差によって、どのように奥行き感が生まれるかを観察してみてください。
観察ポイント
- 速度差が小さいときと大きいときで印象がどう変わるか
- テキストを動かしすぎると読みやすさがどう変わるか
- 背景だけをゆっくり動かした場合に自然さが出るか
- 強い演出より控えめな演出のほうが見やすいか
8.よくある調整パターン
実案件では、次のような調整がよく使われます。
ヒーロー背景だけParallaxにする
最も使いやすいパターンです。
見出しやCTAは固定気味にして、背景だけ少し動かすと破綻しにくいです。
装飾パーツだけParallaxにする
丸やライン、ぼかし要素などを動かす方法です。
軽い印象で入れやすく、情報の邪魔をしにくいです。
セクションごとに別のParallaxを入れる
長いページでは、各セクションで少しずつ異なる速度設定にすると変化が出ます。
ただし、全体でやりすぎると疲れやすいので、アクセントとして使うのが向いています。
9.実装時の注意点
モバイルでは控えめにする
スマホでは画面が狭いため、Parallaxの動きが強いと情報が不安定に見えやすいです。
必要に応じて、モバイルでは速度を弱めるのがおすすめです。
prefers-reduced-motion に配慮する
動きが苦手な人向けに、アニメーションを減らせるようにしておくと親切です。
今回のCSSでも、簡単な無効化を入れています。
演出より可読性を優先する
Parallaxは見た目をよくするための技法ですが、本文やCTAが読みにくくなったら本末転倒です。
特にテキスト周辺は、背景のコントラストも含めて丁寧に調整したいところです。
Parallaxだけでなく、スクロールをトリガーにしたUIパターンを組み合わせることで、よりリッチな体験を作ることができます。
次に読むならこちらがおすすめです。
10.まとめ
Parallax Scroll Animationは、スクロール量に応じて要素ごとの移動量を変えることで、ページに奥行き感を与える表現です。
今回のポイントは次の3つです。
- スクロール量を取得する
- 要素ごとに速度係数を持たせる
transform: translateY()で動かす
仕組み自体はシンプルですが、少し入れるだけでページの印象がかなり良くなります。
まずは今回のサンプルをそのまま動かして、data-speed の値を変えながら感触をつかんでみてください。
Scroll系の演出は、派手さよりも自然さ が大事です。
控えめなParallaxから始めると、使いやすいUIとしてまとまりやすくなります。
UIアニメーションを基礎から順番に学びたい方は、シリーズの最初から読むのがおすすめです。
Scroll Animationシリーズ

コメントを残す