はじめに
長文ページの演出は、派手さよりも「どこを読んでいるか分かること」が大切です。見出しが切り替わるタイミングや、次に読むべき要素が視覚的に伝わるだけで、ページの体験はかなり変わります。
この記事では GSAP と ScrollTrigger を使って、記事ページ向けのスクロール演出を実装します。まずは最小構成で入場演出を作り、次に進捗バーと固定ナビを組み合わせる運用寄りの構成まで広げます。
機能やライブラリの概要
GSAP はアニメーション記述を担当し、ScrollTrigger はスクロール位置とアニメーションの同期を担当します。組み合わせることで、表示タイミング・進捗・固定表示を一貫した設計で扱えます。
記事ページで使うときは、次の3つを先に決めると破綻しにくくなります。
- どの要素をいつ表示させるか
- 戻りスクロール時にどう見せるか
- ヘッダー高さをどこで吸収するか
インストール方法
JavaScript
npm i gsapJavaScript
import { gsap } from "gsap"
import { ScrollTrigger } from "gsap/ScrollTrigger"
gsap.registerPlugin(ScrollTrigger)基本の使い方
最初は、章ブロックがビューポートに入ったときに自然に表示する最小例です。開始位置を固定しておくと、ページの内容が増えても挙動がぶれにくくなります。
HTML
<article class="post">
<section class="js-section">導入</section>
<section class="js-section">比較</section>
<section class="js-section">実装</section>
</article>CSS
.post {
display: grid;
gap: 56px;
}
.js-section {
opacity: 0;
transform: translateY(20px);
}JavaScript
const sections = gsap.utils.toArray(".js-section")
sections.forEach((section) => {
gsap.to(section, {
opacity: 1,
y: 0,
duration: 0.55,
ease: "power2.out",
scrollTrigger: {
trigger: section,
start: "top 78%",
toggleActions: "play none none reverse"
}
})
})この構成は、技術記事、採用ストーリー、事例ページのように「順番に読ませたい」コンテンツで効果が出やすいです。演出が強すぎないため、UIの主役をテキストのまま保てます。
また、セクション単位でトリガーを分離しているので、後から章を追加しても修正範囲が小さく済みます。運用更新が多いメディア案件と相性が良いです。
応用コード
次は、記事進捗バーと目次ナビの固定表示を追加します。構造が増えるので、HTML/CSS/JavaScript をまとめて載せます。
HTML
<header class="reading-ui">
<div class="reading-ui__progress" id="js-progress"></div>
<nav class="reading-ui__toc" id="js-toc">目次</nav>
</header>
<article class="post" id="js-post">...</article>CSS
.reading-ui {
position: sticky;
top: 0;
z-index: 10;
background: rgb(255 255 255 / 88%);
backdrop-filter: blur(8px);
}
.reading-ui__progress {
height: 3px;
transform-origin: left center;
transform: scaleX(0);
background: #0ea5e9;
}JavaScript
const post = document.getElementById("js-post")
const progress = document.getElementById("js-progress")
const toc = document.getElementById("js-toc")
ScrollTrigger.create({
trigger: post,
start: "top top",
end: "bottom bottom",
onUpdate: (self) => {
gsap.set(progress, { scaleX: self.progress })
}
})
ScrollTrigger.create({
trigger: post,
start: "top top+=80",
end: "bottom top+=80",
onEnter: () => toc.classList.add("is-fixed"),
onLeaveBack: () => toc.classList.remove("is-fixed")
})注意点
ScrollTrigger を複数重ねると、開始位置のずれが見えやすくなります。固定ヘッダーがある場合は start と end を必ずヘッダー高さ込みで調整するのが安全です。
さらに、prefers-reduced-motion への配慮は初期段階で入れておくと後戻りを防げます。演出を無効化する分岐を先に用意しておくと、アクセシビリティ対応が楽になります。
まとめ
GSAP ScrollTrigger は、記事ページの読了体験を整える用途で非常に使いやすいです。入場演出、進捗、固定ナビを段階的に追加する設計にすると、見た目と保守性を両立しやすくなります。
まずは最小構成で導入し、ユーザー行動を見ながら演出を足していく進め方がおすすめです。
ポイント
- 派手さより読み順の補助を優先すると失敗しにくい
- 章ごとのトリガー分離で運用時の変更に強くなる
- 固定ヘッダーと reduced motion の考慮を先に入れる