
数字が動的に変化するカウントアップアニメーションを実装したい……



統計や数値を魅力的に表示したい……
今回はこのようなお悩みをお持ちの方へ向けて
Web制作において人気の高いアニメーション効果
カウントアップアニメーション
をご紹介します。
- 基本的なカウントアップ(シンプルな数字の変化)
- フォーマット付きカウントアップ(通貨記号や単位付き)
- イージング付きカウントアップ(スムーズな変化)



特に統計データの表示や成果の可視化には、カウントアップアニメーションが非常に効果的です。この記事のコードをご活用いただきWeb制作の効率化に繋がれば何よりです。
なお、今回ご紹介するアニメーションはCSSとJavaScriptを組み合わせて実装するので、より高度なインタラクションを実現できます。
あわせて読みたい
カウントアップアニメーションとは
カウントアップアニメーションは、数字が0から目標値まで動的に変化するアニメーション効果です。ユーザーの注目を集め、重要な数値を効果的に伝えるための手法です。
効果的な使用場面
適している場面
- 統計データの表示
- 成果や実績の可視化
- ランディングページの数値強調
- ダッシュボードの指標表示
- プログレスバーの数値表示
避けるべき場面
- 頻繁に更新される数値
- 読みやすさを重視する場面
- アクセシビリティを重視する場面
- 過度に使用した場合
実装方法の比較
アニメーション | 難易度 | 視覚的インパクト | パフォーマンス | ブラウザ対応 |
---|---|---|---|---|
基本的なカウントアップ | ⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
フォーマット付きカウントアップ | ⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
イージング付きカウントアップ | ⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ |
基本的なカウントアップ
① デモ
See the Pen 基本的なカウントアップ by ケケンタ (@lgshifbg-the-looper) on CodePen.
- シンプルな数字の変化
- 高いパフォーマンス
- すべてのブラウザで対応
- 読みやすさを保持
② HTML
<!-- スクロール用の領域 -->
<div class="scroll-area">
<div class="scroll-content">
<h2>スクロールしてください</h2>
<p>下にスクロールするとカウントアップアニメーションが表示されます</p>
</div>
</div>
<div class="countup-container">
<div class="countup-item">
<div class="countup-number" data-target="1000">0</div>
<div class="countup-label">ユーザー数</div>
</div>
<div class="countup-item">
<div class="countup-number" data-target="500">0</div>
<div class="countup-label">プロジェクト数</div>
</div>
<div class="countup-item">
<div class="countup-number" data-target="99">0</div>
<div class="countup-label">満足度</div>
</div>
</div>
③ CSS
/* スクロール用の領域 */
.scroll-area {
height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: center;
color: white;
text-align: center;
}
.scroll-content h2 {
font-size: 2.5rem;
margin-bottom: 1rem;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.scroll-content p {
font-size: 1.2rem;
opacity: 0.9;
}
.countup-container {
display: flex;
justify-content: space-around;
align-items: center;
padding: 4rem 2rem;
background: #f8f9fa;
min-height: 60vh;
}
.countup-item {
text-align: center;
padding: 2rem;
}
.countup-number {
font-size: 3.5rem;
font-weight: bold;
color: #667eea;
margin-bottom: 1rem;
font-family: 'Arial', sans-serif;
}
.countup-label {
font-size: 1.2rem;
color: #666;
font-weight: 500;
}
@media (max-width: 768px) {
.countup-container {
flex-direction: column;
gap: 2rem;
}
.countup-number {
font-size: 2.5rem;
}
}
④ JavaScript
document.addEventListener('DOMContentLoaded', function() {
const countupElements = document.querySelectorAll('.countup-number');
// カウントアップ関数
function animateCountup(element, target, duration = 2000) {
const start = 0;
const increment = target / (duration / 16); // 60fps
let current = start;
const timer = setInterval(() => {
current += increment;
if (current >= target) {
current = target;
clearInterval(timer);
}
element.textContent = Math.floor(current);
}, 16);
}
// Intersection Observer for scroll trigger
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const target = parseInt(entry.target.getAttribute('data-target'));
animateCountup(entry.target, target);
observer.unobserve(entry.target); // 一度だけ実行
}
});
}, {
threshold: 0.5
});
countupElements.forEach(el => observer.observe(el));
});
⑤ カスタマイズ例
/* カラーテーマ変更 */
.countup-number {
color: #ff6b6b;
}
/* フォント変更 */
.countup-number {
font-family: 'Courier New', monospace;
}
/* 影効果 */
.countup-number {
text-shadow: 2px 2px 4px rgba(102, 126, 234, 0.3);
}
/* バウンス効果 */
.countup-number {
animation: bounce 0.6s ease-in-out;
}
@keyframes bounce {
0%, 20%, 50%, 80%, 100% {
transform: translateY(0);
}
40% {
transform: translateY(-10px);
}
60% {
transform: translateY(-5px);
}
}
フォーマット付きカウントアップ
① デモ
See the Pen ## フォーマット付きカウントアップ by ケケンタ (@lgshifbg-the-looper) on CodePen.
- 通貨記号や単位の表示
- カンマ区切りの数値
- パーセンテージ表示
- より実用的な表示
② HTML
<!-- スクロール用の領域 -->
<div class="scroll-area">
<div class="scroll-content">
<h2>スクロールしてください</h2>
<p>下にスクロールするとフォーマット付きカウントアップが表示されます</p>
</div>
</div>
<div class="format-countup-container">
<div class="format-countup-item">
<div class="format-countup-number" data-target="1500000" data-prefix="$" data-suffix="">0</div>
<div class="format-countup-label">売上高</div>
</div>
<div class="format-countup-item">
<div class="format-countup-number" data-target="2500" data-prefix="" data-suffix="件">0</div>
<div class="format-countup-label">取引件数</div>
</div>
<div class="format-countup-item">
<div class="format-countup-number" data-target="95" data-prefix="" data-suffix="%">0</div>
<div class="format-countup-label">成功率</div>
</div>
</div>
③ CSS
/* スクロール用の領域 */
.scroll-area {
height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: center;
color: white;
text-align: center;
}
.scroll-content h2 {
font-size: 2.5rem;
margin-bottom: 1rem;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.scroll-content p {
font-size: 1.2rem;
opacity: 0.9;
}
.format-countup-container {
display: flex;
justify-content: space-around;
align-items: center;
padding: 4rem 2rem;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 60vh;
color: white;
}
.format-countup-item {
text-align: center;
padding: 2rem;
}
.format-countup-number {
font-size: 3rem;
font-weight: bold;
margin-bottom: 1rem;
font-family: 'Arial', sans-serif;
}
.format-countup-label {
font-size: 1.2rem;
opacity: 0.9;
font-weight: 500;
}
@media (max-width: 768px) {
.format-countup-container {
flex-direction: column;
gap: 2rem;
}
.format-countup-number {
font-size: 2.2rem;
}
}
④ JavaScript
document.addEventListener('DOMContentLoaded', function() {
const countupElements = document.querySelectorAll('.format-countup-number');
// 数値をフォーマットする関数
function formatNumber(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
// カウントアップ関数(フォーマット付き)
function animateFormatCountup(element, target, duration = 2000) {
const start = 0;
const increment = target / (duration / 16);
let current = start;
const prefix = element.getAttribute('data-prefix') || '';
const suffix = element.getAttribute('data-suffix') || '';
const timer = setInterval(() => {
current += increment;
if (current >= target) {
current = target;
clearInterval(timer);
}
element.textContent = prefix + formatNumber(Math.floor(current)) + suffix;
}, 16);
}
// Intersection Observer for scroll trigger
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const target = parseInt(entry.target.getAttribute('data-target'));
animateFormatCountup(entry.target, target);
observer.unobserve(entry.target);
}
});
}, {
threshold: 0.5
});
countupElements.forEach(el => observer.observe(el));
});
⑤ カスタマイズ例
/* カラーテーマ変更 */
.format-countup-number {
color: #ffd700;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
/* グラデーションテキスト */
.format-countup-number {
background: linear-gradient(45deg, #ffd700, #ff6b6b);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* パルス効果 */
.format-countup-number {
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
}
イージング付きカウントアップ
① デモ
See the Pen イージング付きカウントアップ by ケケンタ (@lgshifbg-the-looper) on CodePen.
- スムーズなイージング効果
- より自然な動き
- 視覚的インパクト大
- プロフェッショナルな印象
② HTML
<!-- スクロール用の領域 -->
<div class="scroll-area">
<div class="scroll-content">
<h2>スクロールしてください</h2>
<p>下にスクロールするとイージング付きカウントアップが表示されます</p>
</div>
</div>
<div class="easing-countup-container">
<div class="easing-countup-item">
<div class="easing-countup-number" data-target="10000">0</div>
<div class="easing-countup-label">ダウンロード数</div>
</div>
<div class="easing-countup-item">
<div class="easing-countup-number" data-target="5000">0</div>
<div class="easing-countup-label">レビュー数</div>
</div>
<div class="easing-countup-item">
<div class="easing-countup-number" data-target="4.8">0</div>
<div class="easing-countup-label">評価</div>
</div>
</div>
③ CSS
/* スクロール用の領域 */
.scroll-area {
height: 100vh;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: center;
color: white;
text-align: center;
}
.scroll-content h2 {
font-size: 2.5rem;
margin-bottom: 1rem;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.scroll-content p {
font-size: 1.2rem;
opacity: 0.9;
}
.easing-countup-container {
display: flex;
justify-content: space-around;
align-items: center;
padding: 4rem 2rem;
background: #2c3e50;
min-height: 60vh;
color: white;
}
.easing-countup-item {
text-align: center;
padding: 2rem;
}
.easing-countup-number {
font-size: 3.5rem;
font-weight: bold;
color: #3498db;
margin-bottom: 1rem;
font-family: 'Arial', sans-serif;
transition: all 0.3s ease;
}
.easing-countup-label {
font-size: 1.2rem;
opacity: 0.9;
font-weight: 500;
}
@media (max-width: 768px) {
.easing-countup-container {
flex-direction: column;
gap: 2rem;
}
.easing-countup-number {
font-size: 2.5rem;
}
}
④ JavaScript
document.addEventListener('DOMContentLoaded', function() {
const countupElements = document.querySelectorAll('.easing-countup-number');
// イージング関数
function easeOutQuart(t) {
return 1 - Math.pow(1 - t, 4);
}
// カウントアップ関数(イージング付き)
function animateEasingCountup(element, target, duration = 2500) {
const start = 0;
const startTime = performance.now();
const isDecimal = target % 1 !== 0;
function update(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
const easedProgress = easeOutQuart(progress);
const current = start + (target - start) * easedProgress;
if (isDecimal) {
element.textContent = current.toFixed(1);
} else {
element.textContent = Math.floor(current);
}
if (progress < 1) {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
}
// Intersection Observer for scroll trigger
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const target = parseFloat(entry.target.getAttribute('data-target'));
animateEasingCountup(entry.target, target);
observer.unobserve(entry.target);
}
});
}, {
threshold: 0.5
});
countupElements.forEach(el => observer.observe(el));
});
⑤ カスタマイズ例
/* カラーテーマ変更 */
.easing-countup-number {
color: #e74c3c;
}
/* グラデーション効果 */
.easing-countup-number {
background: linear-gradient(45deg, #3498db, #e74c3c);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* 回転効果 */
.easing-countup-number {
animation: rotate 0.6s ease-out;
}
@keyframes rotate {
0% {
transform: rotateY(0deg);
}
100% {
transform: rotateY(360deg);
}
}
まとめ
今回ご紹介したカウントアップアニメーションは、Webサイトの数値表示を魅力的にする重要な要素です。
実装のコツ
- 適切なアニメーション時間(1.5秒〜3秒)
- スムーズなイージング関数の使用
- モバイルデバイスでの動作確認
- アクセシビリティの配慮
- パフォーマンスの最適化
避けるべきポイント
- 過度に長いアニメーション時間
- 複雑すぎるイージング
- 読みにくいフォントサイズ
- パフォーマンスを考慮しない実装
- 過度な使用
おすすめの組み合わせ
- シンプルなサイト: 基本的なカウントアップ
- ビジネスサイト: フォーマット付きカウントアップ
- プレミアムサイト: イージング付きカウントアップ



特に統計データの表示や成果の可視化では、カウントアップアニメーションがユーザーエクスペリエンスを大きく左右します。この記事のコードをご活用いただき、より魅力的なWebサイトの制作に繋がれば何よりです。
あわせて読みたい
もっと効率的にWeb制作を学びたい方へ
Web制作の学習は楽しいものですが、一人で進めていると「これで合っているのかな?」と不安になることもありますよね。
僕も独学でWeb制作を学んできましたが、今思うと「もっと早く知りたかった」と思うことがたくさんあります。
特に以下のような方は、一度プログラミングスクールの利用を検討してみることをおすすめします。
- 学習の方向性に迷いがある方
- 効率的にスキルを身につけたい方
- 転職や副業でWeb制作を活用したい方
- 挫折経験がある方
忍者CODEなら、業界最安値で24時間サポート付きの学習環境が整っています。


コメント