実績・数字ヒーロー(カウントアップ)
大見出しの下に、導入社数・稼働率・満足度などの数字がカウントアップして信頼を訴えるヒーロー。BtoBやサービスの実績アピールに効きます。数値が0から目標値まで増えていきます。
ライブデモ
使用例(お題: アイドルグループ Sakura)
この技法を「アイドルグループ Sakura」というテーマのダミーサイトで実際に使った例です。
HTML
<!-- Sakura:実績の数字がカウントアップするヒーロー -->
<section class="ths2">
<div class="ths2-inner">
<p class="ths2-kicker">SAKURA IN NUMBERS</p>
<h1>数字で見る、Sakura。</h1>
<p class="ths2-sub">応援が、こんなに大きな輪になりました。</p>
<div class="ths2-stats" id="ths2Stats">
<div class="ths2-stat"><b data-to="120" data-suffix="万">0</b><span>SNSフォロワー</span></div>
<div class="ths2-stat"><b data-to="3500" data-suffix="万">0</b><span>MV総再生</span></div>
<div class="ths2-stat"><b data-to="48" data-suffix="公演">0</b><span>ツアー</span></div>
<div class="ths2-stat"><b data-to="9" data-suffix="人">0</b><span>メンバー</span></div>
</div>
</div>
</section>
CSS
/* Sakura(アイドル):数字カウントアップ・ヒーローの再スキン */
* { box-sizing: border-box; }
body { margin: 0; font-family: "Hiragino Kaku Gothic ProN", "Segoe UI", system-ui, sans-serif; }
.ths2 { width: 100%; min-height: 380px; display: grid; place-content: center; text-align: center; padding: 40px 26px; color: #fff0f6;
background: radial-gradient(120% 120% at 50% -10%, #7b1d54 0%, #2a0e2e 65%); }
.ths2-inner { max-width: 700px; }
.ths2-kicker { margin: 0 0 14px; font-size: 11px; letter-spacing: .3em; color: #ffb3d2; font-weight: 700; }
.ths2 h1 { margin: 0; font-size: 36px; font-weight: 900; letter-spacing: -.02em; }
.ths2-sub { margin: 14px auto 30px; font-size: 14px; color: rgba(255,255,255,.82); }
.ths2-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.ths2-stat { background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.12); border-radius: 14px; padding: 20px 12px; }
.ths2-stat b { display: block; font-size: 32px; font-weight: 900; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
background: linear-gradient(120deg, #ffc6df, #f8a5cf); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
.ths2-stat span { display: block; margin-top: 8px; font-size: 12px; color: #d8a6c0; }
@media (max-width: 600px) { .ths2-stats { grid-template-columns: repeat(2, 1fr); } }
JavaScript
// (デモと同じフックを流用)数字を0から目標値へカウントアップ(ループ)
(() => {
const wrap = document.getElementById('ths2Stats');
if (!wrap) return;
const nums = [...wrap.querySelectorAll('b')];
const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
const fmt = (v, dec) => (dec ? v.toFixed(dec) : Math.round(v)).toLocaleString('en-US');
function run() {
nums.forEach(el => {
const to = parseFloat(el.dataset.to) || 0;
const dec = parseInt(el.dataset.dec || '0', 10);
const suffix = el.dataset.suffix || '';
if (reduce) { el.textContent = fmt(to, dec) + suffix; return; }
const dur = 1400; let t0 = null;
const ease = (x) => 1 - Math.pow(1 - x, 3);
function step(ts) { if (t0 === null) t0 = ts; const p = Math.min((ts - t0) / dur, 1); el.textContent = fmt(to * ease(p), dec) + suffix; if (p < 1) requestAnimationFrame(step); }
requestAnimationFrame(step);
});
}
run();
if (!reduce) setInterval(run, 4200);
})();
実装ガイド
使いどころ
BtoBやサービス、実績を訴えたいトップに。大見出しの下で、導入社数・稼働率・満足度などの数字がカウントアップして信頼を示します。
実装時の注意点
data-to / data-dec / data-suffix を読み、requestAnimationFrame で 0→目標値へイージング補間。toLocaleString で桁区切りし、tabular-nums で桁ブレを防ぎます。プレビューでは一定間隔で再生し直します。
対応ブラウザ
requestAnimationFrame・Intl の桁区切りは全モダンブラウザ対応。実サイトでは IntersectionObserver で画面到達時に一度だけ発火させるのが定石です。
よくある失敗
誇張した数字は逆効果なので実数で。小数や単位(%・万・ヶ国)の表記を data 属性で正しく。カウント時間が長すぎると待たされ感が出るため1.5秒前後に。reduced-motion では即値表示にフォールバックを。
応用例
到達時に一度だけ再生、ロゴ群(導入企業)の併記、グラフやスパークラインの追加、数値ホバーで内訳表示などに展開できます。
コード
HTML
<!-- 実績の数字がカウントアップするヒーロー -->
<section class="ths2">
<div class="ths2-inner">
<p class="ths2-kicker">TRUSTED WORLDWIDE</p>
<h1>数字が語る、信頼。</h1>
<p class="ths2-sub">導入から運用まで、確かな実績で支えます。</p>
<div class="ths2-stats" id="ths2Stats">
<div class="ths2-stat"><b data-to="1200" data-suffix="+">0</b><span>導入企業</span></div>
<div class="ths2-stat"><b data-to="99.9" data-dec="1" data-suffix="%">0</b><span>稼働率</span></div>
<div class="ths2-stat"><b data-to="4.8" data-dec="1">0</b><span>満足度(5点)</span></div>
<div class="ths2-stat"><b data-to="48" data-suffix="ヶ国">0</b><span>提供地域</span></div>
</div>
</div>
</section>
CSS
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.ths2 {
width: 100%; min-height: 380px; display: grid; place-content: center; text-align: center;
padding: 40px 26px; color: #eef2ff;
background: radial-gradient(120% 120% at 50% -10%, #1e2a6b 0%, #0b1020 65%);
}
.ths2-inner { max-width: 700px; }
.ths2-kicker { margin: 0 0 14px; font-size: 11px; letter-spacing: .3em; color: #8aa0ff; font-weight: 700; }
.ths2 h1 { margin: 0; font-size: 36px; font-weight: 900; letter-spacing: -.02em; }
.ths2-sub { margin: 14px auto 30px; font-size: 14px; color: rgba(255,255,255,.78); }
.ths2-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.ths2-stat { background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.1); border-radius: 14px; padding: 20px 12px; }
.ths2-stat b { display: block; font-size: 34px; font-weight: 900; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
background: linear-gradient(120deg, #a5b4fc, #60a5fa); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
.ths2-stat span { display: block; margin-top: 8px; font-size: 12px; color: #9aa3c8; }
@media (max-width: 600px) { .ths2-stats { grid-template-columns: repeat(2, 1fr); } }
JavaScript
// 数字を0から目標値へカウントアップ(プレビューでは繰り返し再生)
(() => {
const wrap = document.getElementById('ths2Stats');
if (!wrap) return;
const nums = [...wrap.querySelectorAll('b')];
const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
const fmt = (v, dec) => (dec ? v.toFixed(dec) : Math.round(v)).toLocaleString('en-US');
function run() {
nums.forEach(el => {
const to = parseFloat(el.dataset.to) || 0;
const dec = parseInt(el.dataset.dec || '0', 10);
const suffix = el.dataset.suffix || '';
if (reduce) { el.textContent = fmt(to, dec) + suffix; return; }
const dur = 1400; let t0 = null;
const ease = (x) => 1 - Math.pow(1 - x, 3);
function step(ts) {
if (t0 === null) t0 = ts;
const p = Math.min((ts - t0) / dur, 1);
el.textContent = fmt(to * ease(p), dec) + suffix;
if (p < 1) requestAnimationFrame(step);
}
requestAnimationFrame(step);
});
}
run();
if (!reduce) setInterval(run, 4200); // ループ再生
})();
🤖 AIエージェント用プロンプト
このままコピーしてAIに貼り付け「追加する場所」だけ書き換えればOK
あなたは熟練のフロントエンドエンジニアです。私のWebサイトに「実績・数字ヒーロー(カウントアップ)」の効果を追加してください。
# 追加してほしい効果
実績・数字ヒーロー(カウントアップ)(タイトル周り)
大見出しの下に、導入社数・稼働率・満足度などの数字がカウントアップして信頼を訴えるヒーロー。BtoBやサービスの実績アピールに効きます。数値が0から目標値まで増えていきます。
# 追加する場所
👉【ここに対象箇所を記入:例「トップのヒーローセクション」「お問い合わせボタン」「記事カードの一覧」など】
# 参考実装(この見た目・挙動を再現してください)
【HTML】
<!-- 実績の数字がカウントアップするヒーロー -->
<section class="ths2">
<div class="ths2-inner">
<p class="ths2-kicker">TRUSTED WORLDWIDE</p>
<h1>数字が語る、信頼。</h1>
<p class="ths2-sub">導入から運用まで、確かな実績で支えます。</p>
<div class="ths2-stats" id="ths2Stats">
<div class="ths2-stat"><b data-to="1200" data-suffix="+">0</b><span>導入企業</span></div>
<div class="ths2-stat"><b data-to="99.9" data-dec="1" data-suffix="%">0</b><span>稼働率</span></div>
<div class="ths2-stat"><b data-to="4.8" data-dec="1">0</b><span>満足度(5点)</span></div>
<div class="ths2-stat"><b data-to="48" data-suffix="ヶ国">0</b><span>提供地域</span></div>
</div>
</div>
</section>
【CSS】
* { box-sizing: border-box; }
body { margin: 0; font-family: "Segoe UI", system-ui, -apple-system, sans-serif; }
.ths2 {
width: 100%; min-height: 380px; display: grid; place-content: center; text-align: center;
padding: 40px 26px; color: #eef2ff;
background: radial-gradient(120% 120% at 50% -10%, #1e2a6b 0%, #0b1020 65%);
}
.ths2-inner { max-width: 700px; }
.ths2-kicker { margin: 0 0 14px; font-size: 11px; letter-spacing: .3em; color: #8aa0ff; font-weight: 700; }
.ths2 h1 { margin: 0; font-size: 36px; font-weight: 900; letter-spacing: -.02em; }
.ths2-sub { margin: 14px auto 30px; font-size: 14px; color: rgba(255,255,255,.78); }
.ths2-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; }
.ths2-stat { background: rgba(255,255,255,.04); border: 1px solid rgba(255,255,255,.1); border-radius: 14px; padding: 20px 12px; }
.ths2-stat b { display: block; font-size: 34px; font-weight: 900; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
background: linear-gradient(120deg, #a5b4fc, #60a5fa); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
.ths2-stat span { display: block; margin-top: 8px; font-size: 12px; color: #9aa3c8; }
@media (max-width: 600px) { .ths2-stats { grid-template-columns: repeat(2, 1fr); } }
【JavaScript】
// 数字を0から目標値へカウントアップ(プレビューでは繰り返し再生)
(() => {
const wrap = document.getElementById('ths2Stats');
if (!wrap) return;
const nums = [...wrap.querySelectorAll('b')];
const reduce = matchMedia('(prefers-reduced-motion: reduce)').matches;
const fmt = (v, dec) => (dec ? v.toFixed(dec) : Math.round(v)).toLocaleString('en-US');
function run() {
nums.forEach(el => {
const to = parseFloat(el.dataset.to) || 0;
const dec = parseInt(el.dataset.dec || '0', 10);
const suffix = el.dataset.suffix || '';
if (reduce) { el.textContent = fmt(to, dec) + suffix; return; }
const dur = 1400; let t0 = null;
const ease = (x) => 1 - Math.pow(1 - x, 3);
function step(ts) {
if (t0 === null) t0 = ts;
const p = Math.min((ts - t0) / dur, 1);
el.textContent = fmt(to * ease(p), dec) + suffix;
if (p < 1) requestAnimationFrame(step);
}
requestAnimationFrame(step);
});
}
run();
if (!reduce) setInterval(run, 4200); // ループ再生
})();
# 外部ライブラリ
なし(追加ライブラリ不要)
# 守ってほしいこと
- 既存のHTML構造・レイアウト・デザインを壊さないこと。必要に応じてクラス名・色・サイズを私のサイトに合わせて調整してよい。
- クラス名やidが既存と衝突しないよう、必要なら接頭辞で名前空間を分けること。
- レスポンシブ対応と prefers-reduced-motion への配慮を入れること。
- 私のサイトのフレームワーク(React / Vue / 素のHTML など)に合わせて実装すること。不明な場合は素のHTML/CSS/JSで提示し、組み込み手順も説明すること。
- 変更後の確認手順も簡潔に教えてください。