スクロールしているのに、要素そのものは画面内に留まり続ける。
そんな「Sticky UI」は、説明型のレイアウトやストーリー型の見せ方と相性が良いパターンです。
たとえば次のような場面でよく使われます。
- セクションの要点を固定表示したいとき
- スクロールに合わせて演出を進めたいとき
- LPや紹介ページで視線を止めたいとき
この記事では、position: sticky を使った基本の作り方から、
スクロール進行に応じて見た目を変える考え方までを、コピペで試せる形で解説します。
この記事でわかること
position: stickyの基本的な仕組み- Sticky要素が固定される条件
- スクロール量をアニメーションに変換する方法
- Fade / Scale / Move / Combo の実験パターン
1.まずは基本の実装
最初に、Sticky UIの最小構成を確認します。
ここでは 「まず動く」ことを優先したシンプル版 を使います。
HTML
<div class="section">
<div class="sticky">
<h2>Sticky Element</h2>
</div>
<div class="content">
<p>Scroll down to see effect...</p>
<div class="spacer"></div>
</div>
</div>CSS
body {
margin: 0;
font-family: sans-serif;
}
.section {
height: 200vh;
position: relative;
}
.sticky {
position: sticky;
top: 0;
height: 100vh;
background: #111;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
}
.content {
padding: 2rem;
}
.spacer {
height: 150vh;
}JavaScript
window.addEventListener("scroll", () => {
const scrollY = window.scrollY;
const max = document.body.scrollHeight - window.innerHeight;
const progress = scrollY / max;
const sticky = document.querySelector(".sticky");
sticky.style.opacity = 1 - progress;
sticky.style.transform = `scale(${1 - progress * 0.2})`;
});2.この基本コードでやっていること
このコードでは、大きく2つのことをしています。
①Sticky要素を画面上部に固定する
.sticky {
position: sticky;
top: 0;
}これで、Sticky要素は通常の文書フローにいながら、
指定位置に達したあとだけ固定されたように振る舞います。
ただし、ずっと固定され続けるわけではありません。
親要素の範囲内だけ有効 というのがポイントです。
②スクロール量を見た目の変化に変換する
const progress = scrollY / max;この progress は、スクロール全体に対する進行度です。
0に近い → まだ上の方1に近い → かなり下まで進んでいる
この値を使って、
- 透明度を下げる
- 拡大縮小する
- 位置を動かす
といった見た目の変化を作れます。
この考え方は、以前の進行度系の記事ともつながっています。
→ #25 Scroll Progress Animation
3.Stickyの仕組みをもう少し丁寧に見る
position: sticky は、見た目としては「途中から fixed っぽくなる」挙動です。
ただし実際には、親要素の中でだけ固定が成立する特殊なレイアウト と考えると理解しやすいです。
たとえば今回の構造はこうです。
.section
├ .sticky
└ .contentこのとき、.sticky は .section の中で固定されます。
逆に言うと、.section の高さが短すぎると、Stickyらしい見せ方は作れません。
つまり、Sticky UIでは
親要素の高さ = 演出に使えるスクロール距離
と考えると整理しやすいです。
4.progress の取り方
記事内のシンプル版では、ページ全体のスクロール量から progress を求めています。
const max = document.body.scrollHeight - window.innerHeight;
const progress = scrollY / max;これは考え方を理解するには十分です。
ただ、実際のUIでは「ページ全体」ではなく、特定のセクションの中だけで進行度を取りたい ことが多いです。
そこで以下の実験セクションでは、Sticky演出を持つ .sticky-stage を基準にして progress を計算しています。
これによって、
- 他のセクションの影響を受けにくい
- そのセクションだけで演出を完結できる
- Storytelling UI に発展させやすい
というメリットがあります。
この考え方は、トリガー型の制御とも相性が良いです。
→ #28 Scroll Trigger Animation
5.ParallaxやSnapとの違い
Stickyは、スクロール系UIの中でもかなり汎用性が高いです。
ただし、似た見た目でも考え方は少しずつ違います。
Parallaxとの違い
Parallaxは、前景と背景の速度差を使って奥行きを作るパターンです。
Stickyは、ひとつの要素を基準点として留める ことに強みがあります。
背景を動かしたいなら Parallax、
説明の中心を留めたいなら Sticky、という使い分けがしやすいです。
→ #27 Parallax Scroll Animation
6.Scroll Snapとの違い
Scroll Snapは、スクロール位置をセクション単位で吸着させる仕組みです。
Stickyは吸着ではなく、一定区間だけ留まり続ける ことが特徴です。
Snapで区切りをはっきり作りつつ、その中でSticky演出を使う構成もできます。
7.よくあるハマりポイント
Stickyがうまく効かないときは、次を確認すると原因が見つかりやすいです。
親要素に十分な高さがない
Stickyはスクロール距離がないと変化が見えません。
親要素の高さが短いと、固定される時間がほとんどなくなります。
親側に overflow がある
親要素の overflow の指定によっては、期待通りに動かなくなることがあります。
.parent {
overflow: hidden;
}Stickyが効かないときは、まずこの周辺を疑うと早いです。
どこを基準に progress を取っているかが曖昧
ページ全体の進行度を使うのか、
セクション単位の進行度を使うのかで、見え方はかなり変わります。
デモではわかりやすさ重視でページ全体を使ってもいいですが、
実案件ではセクション基準の方が扱いやすいことが多いです。
8.実験
このデモはボタンでアニメーションモードを切り替えられます。
実験①:Fade
透明度だけを変えるパターンです。
Sticky要素を「徐々に消えていく情報」として扱えます。
向いている用途は、導入メッセージやセクション見出しの退場演出です。
実験②:Scale
縮小だけを変えるパターンです。
スクロールが進むほど要素が少しずつ小さくなるため、
「このセクションを読み進めている感覚」を出しやすくなります。
実験③:Move
横移動だけを変えるパターンです。
progress をそのまま translateX() に入れることで、
スクロール量がそのまま移動量になる感覚を確認できます。
実験④:Combo
透明度・縮小・移動を同時に変えるパターンです。
単体の変化よりも演出感が出やすく、
LPやプロダクト紹介ページではこの方向に発展しやすいです。
観察ポイント
次の点を見ると理解しやすいです。
- progress がそのまま UI の値になっていること
- Stickyが「動かない基準点」として機能していること
- 単体変化より、複合変化の方が演出として強く感じやすいこと
- セクション基準で progress を取ると扱いやすいこと
9.まとめ
Sticky Scroll Animation は、見た目はシンプルですが、
スクロールUIの基礎がかなり詰まっています。
今回のポイントは次の3つです。
position: stickyで基準点を作る- scroll progress を 0〜1 の値として扱う
- その値を opacity / scale / translate に変換する
まずは記事内のシンプル版で「動く」ことを確認し、
そのあと実験で Fade / Scale / Move / Combo を切り替えながら比較すると、
Sticky UIの使いどころがかなり見えやすくなります。
Scroll Animationシリーズ

コメントを残す