スクロールに合わせて、左のビジュアルや説明が切り替わるUIを見かけることがあります。
プロダクト紹介、機能説明、サービスLPなどでよく使われる見せ方です。
このUIは、ただ派手なだけではありません。
「ユーザーのスクロール進行に合わせて、見せたい情報を順番に伝えられる」 という強みがあります。
この記事では、Scroll Story UI(実践編) として、
スクロール位置に応じてSTEPごとの内容を切り替えるレイアウトを、初心者にも追いやすい形で実装していきます。
今回は次のような流れで作ります。
- 右側に複数のステップを縦に並べる
- 左側には現在のステップに対応した表示を固定して見せる
- スクロール位置に応じてアクティブな内容を切り替える
- 最低限のJavaScriptで動く形にする
「Scroll Trigger Animationをもう少し実用寄りにしたい」
「Sticky Scroll Animationを、ストーリー型UIとして発展させたい」
という人にもつながる内容です。
1.Scroll Story UIとは?
Scroll Story UIは、スクロールを読み進める行為そのものを、情報の切り替え操作として使うUIです。
たとえば次のような場面で使われます。
- サービスの特徴を順番に紹介したい
- アプリの使い方をステップ形式で見せたい
- 1画面の中で、文章とビジュアルを連動させたい
- 長い説明を、単調にならない形で見せたい
特に、
右側に文章のステップ群
左側に固定されたビジュアルや要約表示
という構成はかなり定番です。
今回の実装でも、この形をベースに進めます。
2.今回作るUIの完成イメージ
今回の完成形は、次のような構成です。
- セクション全体は左右2カラム
- 左カラムは
position: stickyで追従表示 - 右カラムには複数のSTEPカードを並べる
- スクロールして各STEPが見えてくると、左側の表示が切り替わる
- アクティブなSTEPには見た目の強調を入れる
つまり、
右側を読むと、左側の表示が対応して切り替わる
という「読む動き」と「視覚の変化」がつながったUIです。
このあたりの基本となる考え方は、前回の
Sticky Scroll Animationの作り方
ともかなり近いです。
stickyで固定する仕組みがまだ曖昧なら、先にそちらを読むと理解しやすくなります。
また、要素が画面内に入ったことをきっかけに状態を切り替える発想は、
Scroll Trigger Animationの作り方
ともつながっています。
3.先に全体構成を確認する
まずはHTMLの全体像を見ておきます。
.story-shell… 全体ラッパー.story-pin… 左側の固定表示.story-steps… 右側のステップ一覧.story-step… 各ステップ要素data-step… 対応するステップ番号- 左側の表示も
data-panelで切り替える
このように、
右側のSTEPと左側の表示を、番号で対応付ける
だけでもかなりシンプルに作れます。
複雑な状態管理を最初から入れなくても、
「今どのSTEPがアクティブか」
さえ取れれば十分です。
HTML
まずはマークアップです。
<section class="scroll-story">
<div class="story-shell">
<div class="story-pin">
<div class="story-display">
<p class="story-label">Scroll Story UI</p>
<h2 class="story-title">STEP 1</h2>
<p class="story-text">
最初の導入メッセージです。スクロールに合わせて内容が切り替わります。
</p>
<div class="story-panels">
<div class="story-panel is-active" data-panel="1">01</div>
<div class="story-panel" data-panel="2">02</div>
<div class="story-panel" data-panel="3">03</div>
<div class="story-panel" data-panel="4">04</div>
</div>
</div>
</div>
<div class="story-steps">
<article class="story-step is-active" data-step="1">
<span class="step-kicker">STEP 1</span>
<h3>導入で興味を引く</h3>
<p>
最初のステップでは、何について説明するUIなのかを短く伝えます。
ここで読む理由が伝わると、次のステップにも進みやすくなります。
</p>
</article>
<article class="story-step" data-step="2">
<span class="step-kicker">STEP 2</span>
<h3>特徴を整理して見せる</h3>
<p>
2つ目のステップでは、機能や特徴を分かりやすく提示します。
テキストだけでなく、左側の表示を連動させることで理解しやすくなります。
</p>
</article>
<article class="story-step" data-step="3">
<span class="step-kicker">STEP 3</span>
<h3>変化を視覚で補強する</h3>
<p>
スクロールに応じて表示が切り替わると、ユーザーは今どこを読んでいるかを把握しやすくなります。
情報を段階的に見せたいときに有効です。
</p>
</article>
<article class="story-step" data-step="4">
<span class="step-kicker">STEP 4</span>
<h3>最後に印象をまとめる</h3>
<p>
最終ステップでは、全体のまとめや行動導線を置くと相性が良いです。
単なる説明で終わらず、次のアクションにつなげやすくなります。
</p>
</article>
</div>
</div>
</section>CSS
次に見た目を整えます。
左側は sticky、右側は読み進めるための縦並びレイアウトです。
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: sans-serif;
background: #0f1115;
color: #f5f7fb;
}
.scroll-story {
padding: 80px 20px;
}
.story-shell {
max-width: 1100px;
margin: 0 auto;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 40px;
align-items: start;
}
.story-pin {
position: relative;
}
.story-display {
position: sticky;
top: 80px;
min-height: 420px;
padding: 32px;
border-radius: 24px;
background: linear-gradient(180deg, #181d27 0%, #12161d 100%);
border: 1px solid rgba(255,255,255,0.08);
}
.story-label {
margin: 0 0 12px;
font-size: 14px;
letter-spacing: 0.08em;
text-transform: uppercase;
color: #8ea3ff;
}
.story-title {
margin: 0 0 12px;
font-size: 40px;
line-height: 1.1;
}
.story-text {
margin: 0;
font-size: 16px;
line-height: 1.8;
color: rgba(255,255,255,0.8);
max-width: 32ch;
}
.story-panels {
display: flex;
gap: 12px;
margin-top: 28px;
}
.story-panel {
width: 56px;
height: 56px;
display: grid;
place-items: center;
border-radius: 16px;
font-weight: 700;
background: rgba(255,255,255,0.06);
color: rgba(255,255,255,0.5);
transition: 0.3s ease;
}
.story-panel.is-active {
background: #8ea3ff;
color: #10131a;
transform: translateY(-4px);
}
.story-steps {
display: grid;
gap: 24px;
}
.story-step {
min-height: 72vh;
padding: 28px;
border-radius: 24px;
background: rgba(255,255,255,0.04);
border: 1px solid rgba(255,255,255,0.08);
opacity: 0.45;
transform: scale(0.98);
transition: opacity 0.3s ease, transform 0.3s ease, border-color 0.3s ease;
display: flex;
flex-direction: column;
justify-content: center;
}
.story-step.is-active {
opacity: 1;
transform: scale(1);
border-color: rgba(142,163,255,0.6);
}
.step-kicker {
display: inline-block;
margin-bottom: 12px;
font-size: 13px;
letter-spacing: 0.08em;
text-transform: uppercase;
color: #8ea3ff;
}
.story-step h3 {
margin: 0 0 12px;
font-size: 30px;
line-height: 1.3;
}
.story-step p {
margin: 0;
font-size: 16px;
line-height: 1.9;
color: rgba(255,255,255,0.8);
}
@media (max-width: 900px) {
.story-shell {
grid-template-columns: 1fr;
}
.story-display {
position: static;
min-height: auto;
}
.story-step {
min-height: auto;
}
}4.ここまでのポイント
この段階で重要なのは、左側の固定表示をCSSだけで作っていることです。
JavaScriptはまだ使っていませんが、position: sticky; top: 80px;
を入れるだけで、左側の表示がスクロール中に追従してくれます。
この「固定される見せ方」があるだけで、かなりそれっぽいUIになります。
逆にいうと、Scroll Story UIは
アニメーション技術が主役というより、レイアウト設計が主役
の場面も多いです。
スクロール系UIの見せ方を整理したい場合は、
Scroll Snap Animationの作り方
も合わせて読むと比較しやすいです。
snapは「区切って止める」方向、story UIは「読みながら切り替える」方向の違いがあります。
5.JavaScriptでアクティブなSTEPを切り替える
次に、スクロール位置に応じてアクティブなSTEPを切り替えます。
今回はシンプルに、各 .story-step の位置を見て
画面中央に最も近い要素をアクティブ扱い
にします。
<script>
const steps = document.querySelectorAll('.story-step');
const panels = document.querySelectorAll('.story-panel');
const title = document.querySelector('.story-title');
const text = document.querySelector('.story-text');
const contentMap = {
1: {
title: 'STEP 1',
text: '最初の導入メッセージです。スクロールに合わせて内容が切り替わります。'
},
2: {
title: 'STEP 2',
text: '特徴を整理して見せるステップです。左側の表示も連動して変化します。'
},
3: {
title: 'STEP 3',
text: '視覚の変化を加えることで、今どの話を読んでいるかが分かりやすくなります。'
},
4: {
title: 'STEP 4',
text: '最後のまとめや導線設計にも使いやすいのが、Scroll Story UIの良いところです。'
}
};
function setActiveStep(stepNumber) {
steps.forEach(step => {
step.classList.toggle('is-active', step.dataset.step === String(stepNumber));
});
panels.forEach(panel => {
panel.classList.toggle('is-active', panel.dataset.panel === String(stepNumber));
});
title.textContent = contentMap[stepNumber].title;
text.textContent = contentMap[stepNumber].text;
}
function updateActiveStep() {
let closestStep = null;
let closestDistance = Infinity;
steps.forEach(step => {
const rect = step.getBoundingClientRect();
const stepCenter = rect.top + rect.height / 2;
const viewportCenter = window.innerHeight / 2;
const distance = Math.abs(stepCenter - viewportCenter);
if (distance < closestDistance) {
closestDistance = distance;
closestStep = step;
}
});
if (closestStep) {
setActiveStep(closestStep.dataset.step);
}
}
window.addEventListener('scroll', updateActiveStep);
window.addEventListener('resize', updateActiveStep);
updateActiveStep();
</script>6.この実装が分かりやすい理由
このJavaScriptの良いところは、かなり素直なことです。
やっていることは次の3つだけです。
- 各STEPの位置を取得する
- 画面中央に最も近いSTEPを探す
- そのSTEPに対応する左側表示へ切り替える
つまり、
「今いちばん読まれていそうな要素」を選んでいる
だけです。
Intersection Observerを使う方法もありますが、今回のように
「中央基準で自然に切り替えたい」
場合は、まずこの方法のほうが理解しやすいことがあります。
なお、スクロールに応じて状態を更新する考え方は、
Scroll Progressの作り方
ともかなり相性が良いです。
「今どれくらい進んだか」を扱うか、「今どのステップか」を扱うかの違いだけで、発想は近いです。
7.実務で使うときの調整ポイント
実際に使うときは、次の点を調整するとかなり見やすくなります。
①STEPの高さを十分に取る
min-height: 72vh; のように、各ステップにある程度高さを持たせると、
1ステップごとの切り替わりが明確になります。
高さが短すぎると、切り替えが忙しくなり、
ユーザーが「今どこを見ているのか」を感じにくくなります。
②左側は情報を詰め込みすぎない
左側は固定されるぶん、長文を入れると読みにくくなります。
要約・図・番号・短いメッセージなど、
視覚的に一瞬で分かるもの のほうが向いています。
③スマホではstickyを無理に維持しない
モバイルでは左右2カラムが苦しいことが多いです。
今回のようにメディアクエリで1カラムにし、
stickyを外して自然に縦並びへ落とすほうが安全です。
④切り替え演出は控えめでも十分
大きなアニメーションを入れなくても、opacity と transform の変化だけでかなり見やすくなります。
やりすぎると「内容を読むUI」ではなく「動きを見るUI」になりやすいので、
まずは情報の読みやすさを優先するのがおすすめです。
8.どんな場面で相性が良い?
Scroll Story UIは、特に次のようなコンテンツで使いやすいです。
サービス紹介
機能1、機能2、機能3…と順番に説明する場面と相性が良いです。
左側にイメージ図、右側に説明文を置く構成は定番です。
アプリの使い方説明
手順をステップ形式で見せるときに向いています。
画面遷移のように見せるデザインとも相性が良いです。
ストーリー性のあるLP
ブランドの考え方、課題、解決策、導入後の流れ、というように
順を追って読ませたいページで使いやすいです。
ポートフォリオや事例紹介
制作工程や改善プロセスを、
段階的に見せる構成にも合います。
9.単なる見た目で終わらせないために
このUIで大事なのは、
「スクロールに合わせて切り替わること」自体が目的ではない
という点です。
本当に大切なのは、
ユーザーが順番に理解しやすくなること です。
そのためには、各STEPに明確な役割を持たせる必要があります。
たとえば、
- STEP 1 で問題提起
- STEP 2 で特徴紹介
- STEP 3 で具体例
- STEP 4 で導線提示
のように、読み進める意味を作っておくと、
UIの演出が内容の理解を支えてくれます。
見た目だけ似せても、
中身の流れが弱いと「なんとなく動くけど読みにくいUI」になりやすいです。
10.実験:Scroll Story UIを体験してみよう
ここからは、実際に動きを確認するためのデモです。
今回の実験では、左右レイアウトではなく、
縦1カラム+上部sticky表示のミニマム版を使っています。
ブログのように横幅が限られている環境でも、
無理なく使えるScroll Story UIになっています。
観察ポイント
次のポイントを意識してスクロールしてみてください。
- スクロールに応じて、上の表示がどう切り替わるか
- 今読んでいるSTEPと、上部の表示が一致しているか
- activeなSTEPだけ強調されることで、読みやすさがどう変わるか
- 左右レイアウトがなくても、ストーリーとして成立しているか
特に重要なのは、
👉 「読んでいる位置」と「要約表示」が自然にリンクしているか
です。
11.まとめ
Scroll Story UIは、
スクロールを使って順番に情報を見せるUI です。
今回の実装では、
- 左側をstickyで固定
- 右側に複数のステップを配置
- スクロール位置を見てアクティブSTEPを判定
- 左側表示と右側カードを同期
という流れで作りました。
このUIの本質は、
「スクロールで動かすこと」ではなく、
「順番に理解しやすく見せること」 にあります。
Scroll Trigger AnimationやSticky Scroll Animationを、
より実践的なUIに発展させたいときにとても使いやすいパターンです。
Scroll Animationシリーズ

コメントを残す