number-tickerNumber ticker
数字滚动Digits rolling or counting up to a value.
数字滚动或递增到目标值。
Show changing values with tabular figures and stable vertical digit movement.
Digits rolling or counting up to a value.
English definitions are preserved verbatim from Animation Vocabulary; translations and distinctions help you choose precisely.
number-tickerDigits rolling or counting up to a value.
数字滚动或递增到目标值。
tabular-numbersFixed-width digits so numbers don't shift around as they change. Essential for tickers, timers, and counters.
使用固定宽度的数字,使数值变化时不会左右跳动;它对数字滚动、计时器和计数器非常重要。
Tabular numbers is a typographic feature that stabilizes digit width; Number ticker is the animation used when values change.
Purpose, frequency, trigger, timing, interruptibility, and gesture rules shape the implementation.
Roll or count with stable tabular digits to emphasize the direction and magnitude of a value change.
Use for low- to medium-frequency metric updates; batch or replace high-rate live data directly.
Trigger from a confirmed new value, choosing roll direction from increase or decrease.
Roll changed digits to their targets while unchanged digits remain stable, showing the full initial value immediately.
Coalesce successive updates toward the latest value from the current displayed value and velocity.
No gesture is required; numeric increment controls provide keyboard and hold behavior separately.
Replace the value immediately and indicate direction through static color or an arrow.
Current parameters update visual-state CSS, semantic HTML, the required vanilla JS runtime, and an interaction prompt.
.motion-demo.motion-demo--number-ticker {
position: relative;
display: grid;
place-items: center;
width: min(100%, 34rem);
min-height: 15rem;
padding: 2rem;
overflow: hidden;
color: #18181b;
background: #fafafa;
border: 1px solid #e4e4e7;
border-radius: 12px;
isolation: isolate;
}
.motion-demo.motion-demo--number-ticker *, .motion-demo.motion-demo--number-ticker *::before, .motion-demo.motion-demo--number-ticker *::after {
box-sizing: border-box;
}
.motion-demo.motion-demo--number-ticker .motion-surface {
position: relative;
display: grid;
gap: 0.65rem;
width: min(100%, 18rem);
padding: 1.25rem;
background: #ffffff;
border: 1px solid #e4e4e7;
border-radius: 8px;
box-shadow: 0 1px 2px rgb(0 0 0 / 6%), 0 10px 28px rgb(0 0 0 / 7%);
}
.motion-demo.motion-demo--number-ticker .motion-line {
display: block;
width: 100%;
height: 0.5rem;
background: #e4e4e7;
border-radius: 999px;
}
.motion-demo.motion-demo--number-ticker .motion-line:last-child { width: 62%; }
.motion-demo.motion-demo--number-ticker .motion-button {
position: relative;
min-height: 2.75rem;
padding: 0.75rem 1.1rem;
color: white;
font: inherit;
font-weight: 700;
background: #18181b;
border: 0;
border-radius: 7px;
cursor: pointer;
}
.motion-demo.motion-demo--number-ticker .motion-button:focus-visible { outline: 3px solid rgb(37 99 235 / 32%); outline-offset: 3px; }
.motion-demo.motion-demo--number-ticker .motion-action-row {
display: flex;
justify-content: center;
gap: 0.5rem;
margin-top: 0.85rem;
}
.motion-demo.motion-demo--number-ticker .motion-replay-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--number-ticker .motion-pausable-scene {
width: min(100%, 22rem);
display: grid;
place-items: center;
}
.motion-demo.motion-demo--number-ticker button.motion-surface {
color: inherit;
font: inherit;
text-align: start;
cursor: pointer;
}
.motion-demo.motion-demo--number-ticker .motion-replay-button,
.motion-demo.motion-demo--number-ticker .motion-undo-button,
.motion-demo.motion-demo--number-ticker .motion-dismiss-button,
.motion-demo.motion-demo--number-ticker .motion-pause-button {
min-height: 2.75rem;
padding: 0.65rem 0.9rem;
color: #18181b;
font: 650 0.78rem/1 ui-sans-serif, system-ui, sans-serif;
background: #ffffff;
border: 1px solid #d4d4d8;
border-radius: 7px;
cursor: pointer;
}
.motion-demo.motion-demo--number-ticker .motion-replay-button:focus-visible,
.motion-demo.motion-demo--number-ticker .motion-undo-button:focus-visible,
.motion-demo.motion-demo--number-ticker .motion-dismiss-button:focus-visible,
.motion-demo.motion-demo--number-ticker .motion-pause-button:focus-visible,
.motion-demo.motion-demo--number-ticker [data-reorder-item]:focus-visible,
.motion-demo.motion-demo--number-ticker [data-swipe-target]:focus-visible {
outline: 3px solid rgb(37 99 235 / 32%);
outline-offset: 3px;
}
.motion-demo.motion-demo--number-ticker .motion-status {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.motion-demo.motion-demo--number-ticker .motion-ripple-ink {
position: absolute;
width: 12px;
height: 12px;
pointer-events: none;
background: rgb(255 255 255 / 72%);
border-radius: 50%;
transform: translate(-50%, -50%) scale(0.95);
opacity: 0;
}
.motion-demo.motion-demo--number-ticker .motion-state-stack { position: relative; width: min(100%, 18rem); height: 9rem; }
.motion-demo.motion-demo--number-ticker .motion-state { position: absolute; inset: 0; display: grid; place-items: center; padding: 1rem; background: #ffffff; border: 1px solid #e4e4e7; border-radius: 8px; }
.motion-demo.motion-demo--number-ticker .motion-state--to { background: #18181b; color: white; }
.motion-demo.motion-demo--number-ticker .motion-scroll-track > span { color: #71717a; font: 600 0.72rem/1.2 ui-monospace, monospace; letter-spacing: 0.08em; text-transform: uppercase; }
.motion-demo.motion-demo--number-ticker .motion-orbit-item { display: grid; place-items: center; width: 2.5rem; height: 2.5rem; color: white; background: #2563eb; border-radius: 50%; }
.motion-demo.motion-demo--number-ticker .motion-text-stack { position: relative; width: min(100%, 18rem); min-height: 4rem; }
.motion-demo.motion-demo--number-ticker svg { width: min(100%, 20rem); height: auto; }
.motion-demo.motion-demo--number-ticker .motion-number { height: 1.2em; overflow: hidden; font: 700 3rem/1.2 ui-monospace, monospace; font-variant-numeric: tabular-nums; }
.motion-demo.motion-demo--number-ticker .motion-number-track { display: grid; animation: motion-number-ticker 240ms cubic-bezier(0.16, 1, 0.3, 1) both; }
@keyframes motion-number-ticker { from { transform: translateY(24px); opacity: 0; } to { transform: none; opacity: 1; } }
@keyframes motion-number-ticker-reduced-fade {
from { opacity: 0.84; }
to { opacity: 1; }
}
.force-reduced-motion .motion-demo.motion-demo--number-ticker {
animation: motion-number-ticker-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.force-reduced-motion .motion-demo.motion-demo--number-ticker *,
.force-reduced-motion .motion-demo.motion-demo--number-ticker *::before,
.force-reduced-motion .motion-demo.motion-demo--number-ticker *::after {
animation: none !important;
animation-delay: 0ms !important;
animation-iteration-count: 1 !important;
transition-property: opacity, color, background-color, border-color !important;
transition-duration: 160ms !important;
transition-delay: 0ms !important;
scroll-behavior: auto !important;
}
.force-reduced-motion .motion-demo.motion-demo--number-ticker .motion-button,
.force-reduced-motion .motion-demo.motion-demo--number-ticker [data-reorder-item],
.force-reduced-motion .motion-demo.motion-demo--number-ticker [data-swipe-target],
.force-reduced-motion .motion-demo.motion-demo--number-ticker [data-spring-target] {
transform: none !important;
}
.force-reduced-motion .motion-demo.motion-demo--number-ticker .motion-path { stroke-dashoffset: 0 !important; }
.force-reduced-motion .motion-demo.motion-demo--number-ticker .motion-word--from { opacity: 0 !important; visibility: hidden; }
.force-reduced-motion .motion-demo.motion-demo--number-ticker .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
@media (prefers-reduced-motion: reduce) {
.motion-demo.motion-demo--number-ticker {
animation: motion-number-ticker-reduced-fade 160ms cubic-bezier(0.23, 1, 0.32, 1) both !important;
}
.motion-demo.motion-demo--number-ticker *, .motion-demo.motion-demo--number-ticker *::before, .motion-demo.motion-demo--number-ticker *::after {
animation: none !important;
animation-delay: 0ms !important;
animation-iteration-count: 1 !important;
transition-property: opacity, color, background-color, border-color !important;
transition-duration: 160ms !important;
transition-delay: 0ms !important;
scroll-behavior: auto !important;
}
.motion-demo.motion-demo--number-ticker .motion-button,
.motion-demo.motion-demo--number-ticker [data-reorder-item],
.motion-demo.motion-demo--number-ticker [data-swipe-target],
.motion-demo.motion-demo--number-ticker [data-spring-target] {
transform: none !important;
}
.motion-demo.motion-demo--number-ticker .motion-path { stroke-dashoffset: 0 !important; }
.motion-demo.motion-demo--number-ticker .motion-word--from { opacity: 0 !important; visibility: hidden; }
.motion-demo.motion-demo--number-ticker .motion-word:not(.motion-word--from) { opacity: 1 !important; filter: none !important; transform: none !important; }
}Replace the value immediately and indicate direction through static color or an arrow.
| Parameter | Range / options | Default | Purpose |
|---|---|---|---|
duration | 80ms–1200ms | 240ms | Controls the time required for one motion cycle. |
distance | 0px–60px | 24px | Controls how far the element travels. |
ease | Soft / Snap / Calm / Linear | Snap | Controls how velocity changes over time. |