カウントアップ
stimeo--count-up
マークアップに書かれた最終値まで、数値をアニメーションで増やしていく。定番は「見えたら開始」。
stimeo--count-up は、DOM に既に書かれている値まで数字を from からアニメーションさせ、終了時に作者のテキスト(区切り文字・接尾辞込み)をそのまま復元します — SEO・no-JS・スクリーンリーダーは常に本当の値を持ちます。開始は start アクションで自由に束ねられ、定番は intersection プリミティブとのマークアップ合成(data-action="stimeo--intersection:enter->stimeo--count-up#start")です。 prefers-reduced-motion ではアニメ自体をスキップし、実行中は aria-label に最終値を保持するため、支援技術が中間の数字を読み上げることはありません。once(既定)では実行済みが data-count-up-done として記録され、Turbo のキャッシュ復元後も尊重されます。
統計をスクロールで表示してください — 各タイルは intersection(契機)と count-up(演出)のマークアップ合成です。最終値はマークアップに残っています。
- ユーザー数
- 12,480
- GitHub スター
- 3,200
- 稼働率(%)
- 99
<%# count-up: the final numbers stay authored in the markup (SEO / no-JS / SR read
the real values); each stat composes intersection ("start when visible") with
count-up via data-action. Scroll the stats into view to run the animation. %>
<div class="count-up-demo">
<p class="count-up-demo__hint"><%= t("components.count_up.demo.hint") %></p>
<dl class="count-up-demo__stats">
<div class="count-up-demo__stat">
<dt><%= t("components.count_up.demo.stats.users") %></dt>
<dd data-controller="stimeo--intersection stimeo--count-up"
data-stimeo--intersection-once-value="true"
data-action="stimeo--intersection:enter->stimeo--count-up#start">12,480</dd>
</div>
<div class="count-up-demo__stat">
<dt><%= t("components.count_up.demo.stats.stars") %></dt>
<dd data-controller="stimeo--intersection stimeo--count-up"
data-stimeo--intersection-once-value="true"
data-action="stimeo--intersection:enter->stimeo--count-up#start">3,200</dd>
</div>
<div class="count-up-demo__stat">
<dt><%= t("components.count_up.demo.stats.uptime") %></dt>
<dd data-controller="stimeo--intersection stimeo--count-up"
data-stimeo--intersection-once-value="true"
data-action="stimeo--intersection:enter->stimeo--count-up#start">99</dd>
</div>
</dl>
</div>
/*
* Presentation-only styles for the count-up demo. The library animates the text
* content; this CSS only lays out the stat tiles.
*/
.count-up-demo {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.count-up-demo__hint {
margin: 0;
color: var(--muted);
}
.count-up-demo__stats {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin: 0;
}
.count-up-demo__stat {
min-width: 10rem;
padding: 1rem;
border: 1px solid var(--border);
border-radius: 0.5rem;
background: var(--bg);
}
.count-up-demo__stat dt {
color: var(--muted);
font-size: 0.9rem;
}
.count-up-demo__stat dd {
margin: 0.25rem 0 0;
font-size: 1.75rem;
font-weight: 700;
font-variant-numeric: tabular-nums;
}
このデモに固有の消費側 JS はありません(挙動はコントローラが担います)。
これらのスタイルは共通のデザイントークン(ライト/ダーク両対応)を使います。 共通スタイルも一緒にコピーし、ルート要素の data-theme を切り替えればダークになります。
このコンポーネントを動かすために HTML へ記述する data-* 属性です。ルート要素に下の data-controller を付け、その内側に各 target / value / action を配置します。
ルート要素に付与
data-controller="stimeo--count-up"
値(Values)
| 名前 | 説明 | 属性 |
|---|---|---|
duration
|
アニメ時間(ms)。既定 1200。 | data-stimeo--count-up-duration-value |
from
|
開始値。既定 0。 | data-stimeo--count-up-from-value |
once
|
一度きり(data-count-up-done で記録)。既定 true。 |
data-stimeo--count-up-once-value |
アクション
| 名前 | 説明 | アクション |
|---|---|---|
start
|
アニメを開始する(例: data-action で stimeo--intersection:enter に束ねる)。 |
stimeo--count-up#start |
イベント
| 名前 | 説明 | イベント |
|---|---|---|
end
|
確定時に { value } と共に発火(reduced-motion スキップ時も)。 |
stimeo--count-up:end |
状態フック
ライブラリが操作するのはこれらの ARIA / data 属性、カスタムプロパティだけです。見た目は利用側 CSS がこれらに反応して作ります([aria-selected] / [aria-expanded] / var(--stimeo--…) などのセレクタでフックします)。
| フック | 対象 | 意味 |
|---|---|---|
data-count-up-done |
コントローラ要素 | 実行済みマーカー。once が有効な間の再実行を抑止する。 |
aria-label(実行中のみ) |
コントローラ要素 | アニメ中も支援技術には作者の最終値を伝える。 |