No.116
SCROLL CSS

Scroll Driven Progress

animation-timeline: scroll() でJavaScript不要の読了プログレスバー。スクロール量をアニメーションに直結させるCSSの新機能。

DEMO

SCROLL ME

この枠の中をスクロールすると、上部のバーが伸びます。JavaScript は1行も使っていません。

スクロール量そのものをアニメーションの再生ヘッドに割り当てる CSS Scroll-driven Animations の機能です。

スクロールイベントを購読しないため、メインスレッドを止めずに滑らかに追従します。

記事ページの読了率バー、ランディングページの進捗インジケーターに使えます。

未対応のブラウザではバーが満タンのまま表示され、レイアウトは壊れません。

END

CODE

HTML
<div class="demo-stage sdp-stage">
  <div class="sdp-scroller">
    <div class="sdp-track"><div class="sdp-bar"></div></div>
    <div class="sdp-content">
      <p class="sdp-lead">SCROLL ME</p>
      <p class="sdp-p">この枠の中をスクロールすると、上部のバーが伸びます。JavaScript は1行も使っていません。</p>
      <p class="sdp-p">スクロール量そのものをアニメーションの再生ヘッドに割り当てる CSS Scroll-driven Animations の機能です。</p>
      <p class="sdp-p">スクロールイベントを購読しないため、メインスレッドを止めずに滑らかに追従します。</p>
      <p class="sdp-p">記事ページの読了率バー、ランディングページの進捗インジケーターに使えます。</p>
      <p class="sdp-p">未対応のブラウザではバーが満タンのまま表示され、レイアウトは壊れません。</p>
      <p class="sdp-end">END</p>
    </div>
  </div>
</div>
CSS
.sdp-stage { position:relative; min-height:280px; background:#0F0F12; padding:0; overflow:hidden; }
.sdp-scroller {
  height:320px; overflow-y:auto; scroll-timeline: --sdp-scroll block;
}
.sdp-track {
  position:sticky; top:0; z-index:2; height:4px; background:rgba(255,255,255,.08);
}
.sdp-bar {
  height:100%; width:100%; transform-origin:0 50%;
  background:linear-gradient(90deg,#E91B89,#7B37A8,#5BAADE);
}
@supports (animation-timeline: scroll()) {
  .sdp-bar {
    animation: sdp-grow linear both;
    animation-timeline: --sdp-scroll;
  }
}
@keyframes sdp-grow { from { transform:scaleX(0); } to { transform:scaleX(1); } }
.sdp-content { padding:2rem 2rem 3rem; }
.sdp-lead { font-family:'Oswald',sans-serif; font-size:.8rem; letter-spacing:.3em; color:#E91B89; margin-bottom:1.2rem; }
.sdp-p { font-size:.9rem; line-height:1.9; color:#B9B9C2; margin-bottom:1.4rem; }
.sdp-end { font-family:'Oswald',sans-serif; font-size:1.4rem; letter-spacing:.2em; color:#fff; padding-top:1rem; }
@media (prefers-reduced-motion: reduce) {
  .sdp-bar { animation:none; transform:scaleX(1); }
}

AI PROMPT

Claude Code Cursor v0
PROMPT
JavaScriptを使わずに読了プログレスバーを作って。スクロールする要素に scroll-timeline: --名前 block; を宣言し、その子孫にあるバーへ animation-timeline: --名前; を指定する。バーのkeyframesは from { transform: scaleX(0) } to { transform: scaleX(1) } とし、transform-origin: 0 50% で左端起点に。バーは position: sticky; top: 0 のトラックに入れて常時見えるようにする。ページ全体で使う場合は scroll-timeline の宣言を省き animation-timeline: scroll() だけで document のスクロールに直結できる。重要: 非対応ブラウザで消えないよう、既定は transform: scaleX(1)(満タン)にしておき、@supports (animation-timeline: scroll()) の中だけで animation を当てること。scaleX なのでレイアウトを再計算せず、コンポジタスレッドで動くため軽い。

Acceptance criteria: works with prefers-reduced-motion (animation disabled), zero console errors, zero layout shift

AIエージェントでの実装ガイド → Claude Code でWebアニメーションを実装する

BOOKS · PR · AMAZON

📖 なかしまぁ先生のCSSアニメーション入門 📖 UIデザインの教科書 新版 マルチデバイス時代のインターフェース設計 📖 Fundamentals of Web Animation with GSAP

※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。

学びを止めない · AMAZONサブスク

📚 Kindle Unlimited — 技術書・デザイン書が読み放題。30日無料体験 → 🎧 Audible — 移動中に耳で学ぶオーディオブック。30日無料体験 → 📦 Amazon Prime — Prime Reading・配送特典つき。30日無料体験 → 🎵 Music Unlimited — 作業用BGMに。1億曲が聴き放題・30日無料体験 →

※当サイトはAmazonアソシエイトプログラムの参加者です。リンクから商品をご購入いただくと、当方に紹介料が発生します。

RELATED EFFECTS

↗ MORE
→ SCROLL PROGRESS BAR → SCROLL REVEAL VIEW TIMELINE → STICKY SECTIONS

Scroll Driven Progress(CSSスクロール連動バー)とは

スクロール量をそのままアニメーションの再生ヘッドに割り当てる CSS Scroll-driven Animations の最も基本的な使い方です。スクロールする要素に scroll-timeline を名付け、進捗バーに animation-timeline でその名前を渡すだけで、JavaScript のスクロールイベントを一切書かずに読了バーが完成します。

当サイトの Scroll Progress Bar は同じ見た目を JavaScript(scroll イベント+スクロール率の計算)で実装した従来型で、対応ブラウザを問わず動くのが強みです。本ページはそれを CSS だけに置き換えた新仕様版という別テーマになります。既存プロジェクトの置き換えを検討する場合は、両方を見比べてから選んでください。

実装で最も事故が多いのは「非対応ブラウザでバーが scaleX(0) のまま消える」パターンです。@supports で機能検出し、既定値を可視状態にしてから機能ブロック内でアニメーションを当てる、という順序を必ず守ってください。

よくある質問

Scroll-driven Animations とは何ですか?

スクロール量をアニメーションの再生位置に直結させるCSSの仕様です。従来は scroll イベントを購読してJavaScriptで進捗を計算していた処理を、animation-timeline: scroll() というCSSの1行に置き換えられます。イベント購読が不要なのでメインスレッドを塞がず、スクロールに完全同期した滑らかな動きになります。

対応していないブラウザではどうなりますか?

@supports (animation-timeline: scroll()) で囲っておけば、非対応ブラウザではアニメーションが適用されず、CSSで指定した既定の状態がそのまま表示されます。本ページのコードは既定を「バーが満タン」にしてあるため、非対応環境でも空欄や消失にはなりません。この既定値の設計が最も重要なポイントです。

コードは無料で使えますか?

はい。Motion LabのコードスニペットとAIプロンプトは、クレジット表記なしで自由に使えます。コピーしてそのままプロジェクトに利用できます。