ちいつる

スクロールアニメーション

数字カウントアップ

画面に入ると数字が0から目標値へ駆け上がる。実績や統計の見せ場に。

ENGLISH

Count Up Animation

  • JS
39スクロールアニメーション の一覧 →

プレビュー

スクロール

操作枠内をスクロールすると動きます。

使いどころ

実績や統計を「数字そのものが主役」として見せたいときに向く。導入企業数、累計ダウンロード数、削減できた時間のように、大きさ自体が説得材料になる数値と相性がよい。0から目標値へ駆け上がる動きは視線を引きつけ、その数字を読ませたいという意図をはっきり伝えられる。一方で、価格やユーザーの残高、在庫数のように「正確な値をすぐ知りたい」数字をカウントアップさせるのは避けたい。確定するまで読めないうえ、途中の値が一瞬でも本当の値のように見えてしまう。ダッシュボードで頻繁に更新される数値も、動くたびに注意が奪われるため静的に出す方が使いやすい。同じ画面に並べる数字は3〜4個までにし、それぞれ少しずつ開始をずらすと順に読ませられる。

仕組み

IntersectionObserver で要素が画面に入ったことを検知し、そこからアニメーションを始める。スクロールイベントで位置を計算する必要はなく、observer に任せる方が軽く、実装も短い。1回だけ動かせばよいので、発火したら unobserve するのを忘れないようにする。数値の更新は requestAnimationFrame のループで、経過時間を持続時間で割った進捗(0〜1)から現在値を求める形にする。進捗にイージング(終盤を緩める ease-out 系)をかけると、目標値に「着地する」感触が出て、ただの線形増加より気持ちよくなる。表示は toLocaleString() で桁区切りを付け、小数を含む場合は toFixed() で桁数を固定して揺れないようにする。持続時間は1.5〜2秒程度が目安で、長すぎると読みたい人を待たせる。

実装の注意

桁区切りが入る数値では、カンマが増減するたびに文字幅が変わってレイアウトが揺れる。font-variant-numeric: tabular-nums を指定して数字の字幅を揃え、さらに最終値の幅を min-width で確保しておくと安定する。setInterval で一定量ずつ足す実装も見かけるが、端末の性能やタブの状態で所要時間が変わるうえ、刻み幅の丸めで最終値がぴったりにならないことがある。requestAnimationFrame と経過時間から計算すれば、どの端末でも同じ時間で同じ値に着地する。画面に入る前の初期表示を0にしておくと、JavaScriptが無効・失敗した環境で「0」が残って誤情報になる。HTMLには最終値を書いておき、スクリプトが動いたときだけ0から始めるのが安全。ファーストビューに置く場合は、observer が即座に発火してページ読み込みの慌ただしさと重なるため、少し遅延させると落ち着く。

アクセシビリティ

刻々と変わる数値が live region に入っていると、スクリーンリーダーが中間値を延々と読み上げることになる。アニメーションする要素には aria-hidden="true" を付け、最終値を持つ静的な要素(sr-only)を併置してそちらを読ませる。prefers-reduced-motion: reduce では、カウントアップをせず最初から最終値を表示する。この対応は単に演出を省くだけでなく、動く数字を目で追うのが負担になるユーザーにとって実質的な改善になる。数字だけを大きく出して単位や説明を小さくしすぎると、拡大表示のユーザーが文脈を見失いやすい。「1,200」ではなく「導入企業 1,200社」のように、数値と意味が同じ塊として読める順序でマークアップしておきたい。

調整して使う

触る値は持続時間・イージング・開始のタイミング。持続時間は1.2〜2秒が読みやすい範囲で、桁数が多い数字ほど長め(ただし2.5秒まで)にする。イージングは終盤を緩める ease-out 系にすると着地感が出る。線形だと最後まで同じ速さで動き、止まった瞬間が唐突に見える。複数の数字を並べるときは開始を100〜200msずつずらすと、左から順に読ませる流れが作れる。接頭・接尾の単位(「¥」「万件」「%」)はカウントさせず静的に置くのが基本で、数字部分だけを tabular-nums にして幅を固定する。増加を強調したいなら、着地の瞬間に色を一瞬明るくするか、わずかな scale のバウンドを足すと「到達した」感触が加わる。

コード(コピーして使えます)

<div class="scroll-hint">↓ スクロール ↓</div>
<div class="count-block">
  <div class="counter" data-target="1280">0</div>
  <p class="counter-cap">ダウンロード数</p>
</div>

タグ

関連パーツ