スクロールに追従するUIの作り方(Sticky Animation)

Sticky Scroll Animationのアイキャッチ画像

スクロールしているのに、要素そのものは画面内に留まり続ける。
そんな「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演出を使う構成もできます。

#26 Scroll Snap Animation

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シリーズ

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA