Live Price Ticker
A static price is history; an animated price is now. Green or red flash on each update tells direction without comparison. Sparkline shows the recent walk. The animation IS the signal.
Live Price Ticker the 16th of 30 designs in the 30 CSS Badges collection. The design pairs CSS styling with a small amount of JavaScript for interactivity. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.
Live preview
The code
<div class="price-stage">
<div class="price-card" id="price-card">
<div class="price-top">
<div class="price-symbol">BTC · USD</div>
<div class="price-live-dot">Live · 3s</div>
</div>
<div class="price-value" id="price-value">$67,420.58</div>
<div class="price-change">
<span class="price-delta price-up" id="price-delta">+$234.12</span>
<span class="price-delta price-up" id="price-pct">(+0.35%)</span>
<span class="price-arrow" id="price-arrow">▲</span>
</div>
<svg class="price-sparkline" viewBox="0 0 200 36" preserveAspectRatio="none" aria-hidden="true">
<defs>
<linearGradient id="price-spark-grad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#0cce6b" stop-opacity="0.3"/>
<stop offset="100%" stop-color="#0cce6b" stop-opacity="0"/>
</linearGradient>
</defs>
<path id="price-spark-area" fill="url(#price-spark-grad)" opacity="0.6"/>
<polyline id="price-spark-line" class="price-sparkline-path" stroke="#0cce6b"/>
</svg>
<div class="price-footer">
<span id="price-updated">Updated just now</span>
<span>24h Vol $42.8B</span>
</div>
</div>
</div> .price-stage {
background: #0d1117;
padding: 48px 36px;
display: flex;
justify-content: center;
align-items: center;
min-height: 360px;
}
.price-card {
background: #161b22;
border: 1px solid #30363d;
border-radius: 8px;
padding: 22px 24px;
width: 100%;
max-width: 380px;
position: relative;
overflow: hidden;
font-family: ui-monospace, "JetBrains Mono", monospace;
}
.price-card.is-flash-up { animation: price-flash-up 0.65s ease-out; }
.price-card.is-flash-down { animation: price-flash-down 0.65s ease-out; }
@keyframes price-flash-up { 0% { background: rgba(12,206,107,0.2); } 100% { background: #161b22; } }
@keyframes price-flash-down { 0% { background: rgba(255,78,66,0.2); } 100% { background: #161b22; } }
@media (prefers-reduced-motion: reduce) {
.price-card.is-flash-up, .price-card.is-flash-down { animation: none; }
}
.price-top {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 8px;
}
.price-symbol {
font-size: 11px;
letter-spacing: 0.18em;
color: #8b949e;
text-transform: uppercase;
}
.price-live-dot {
display: flex;
align-items: center;
gap: 6px;
font-family: system-ui, "Bricolage Grotesque", sans-serif;
font-size: 9px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: #8b949e;
}
.price-live-dot::before {
content: '';
display: block;
width: 6px;
height: 6px;
border-radius: 50%;
background: #0cce6b;
box-shadow: 0 0 6px #0cce6b;
animation: price-pulse 2s infinite;
}
@keyframes price-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }
.price-value {
font-size: 36px;
font-weight: 700;
color: #e6edf3;
letter-spacing: -0.02em;
margin-bottom: 6px;
line-height: 1;
}
.price-change {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 14px;
}
.price-delta {
font-size: 13px;
font-weight: 600;
}
.price-up { color: #0cce6b; }
.price-down { color: #ff4e42; }
.price-arrow { font-size: 12px; }
.price-sparkline { width: 100%; height: 36px; }
.price-sparkline-path {
fill: none;
stroke-width: 1.5;
stroke-linecap: round;
stroke-linejoin: round;
}
.price-footer {
display: flex;
justify-content: space-between;
margin-top: 10px;
padding-top: 10px;
border-top: 1px solid #21262d;
font-size: 9px;
letter-spacing: 0.1em;
color: #8b949e;
text-transform: uppercase;
} // Live price ticker — random-walks BTC around $67k. Every 3s the
// price moves, the delta + sparkline update, and the background
// flashes green or red depending on direction.
(function () {
var price = 67420.58;
var openPrice = 67186.46;
var history = [];
for (var k = 0; k < 24; k++) {
history.push(67186 + Math.sin(k * 0.7) * 180 + k * 9.8 + Math.random() * 60);
}
history.push(price);
var card = document.getElementById('price-card');
var valEl = document.getElementById('price-value');
var deltaEl = document.getElementById('price-delta');
var pctEl = document.getElementById('price-pct');
var arrowEl = document.getElementById('price-arrow');
var lineEl = document.getElementById('price-spark-line');
var areaEl = document.getElementById('price-spark-area');
var updEl = document.getElementById('price-updated');
function fmt(n) {
return n.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
}
function redrawSpark() {
var W = 200, H = 36, pad = 2;
var min = Math.min.apply(null, history);
var max = Math.max.apply(null, history);
var range = max - min || 1;
var pts = history.map(function (v, i) {
var x = (i / (history.length - 1)) * (W - 2 * pad) + pad;
var y = H - pad - ((v - min) / range) * (H - 2 * pad);
return x.toFixed(1) + ',' + y.toFixed(1);
}).join(' ');
lineEl.setAttribute('points', pts);
var areaD = 'M ' + pad + ' ' + H + ' L ' + history.map(function (v, i) {
var x = (i / (history.length - 1)) * (W - 2 * pad) + pad;
var y = H - pad - ((v - min) / range) * (H - 2 * pad);
return x.toFixed(1) + ' ' + y.toFixed(1);
}).join(' L ') + ' L ' + (W - pad) + ' ' + H + ' Z';
areaEl.setAttribute('d', areaD);
}
function updatePrice() {
var prev = price;
price += (Math.random() - 0.47) * 110;
price = Math.max(64000, Math.min(72000, price));
history.push(price);
if (history.length > 24) history.shift();
var isUp = price >= prev;
var totalChange = price - openPrice;
var totalPct = (totalChange / openPrice) * 100;
valEl.textContent = '$' + fmt(price);
deltaEl.textContent = (totalChange >= 0 ? '+$' : '-$') + fmt(Math.abs(totalChange));
pctEl.textContent = '(' + (totalPct >= 0 ? '+' : '') + totalPct.toFixed(2) + '%)';
arrowEl.textContent = isUp ? '▲' : '▼';
arrowEl.style.color = isUp ? '#0cce6b' : '#ff4e42';
var cls = isUp ? 'price-up' : 'price-down';
deltaEl.className = 'price-delta ' + cls;
pctEl.className = 'price-delta ' + cls;
document.querySelectorAll('#price-spark-grad stop').forEach(function (s) {
s.setAttribute('stop-color', isUp ? '#0cce6b' : '#ff4e42');
});
lineEl.setAttribute('stroke', isUp ? '#0cce6b' : '#ff4e42');
card.classList.remove('is-flash-up', 'is-flash-down');
void card.offsetWidth;
card.classList.add(isUp ? 'is-flash-up' : 'is-flash-down');
updEl.textContent = 'Updated just now';
redrawSpark();
}
redrawSpark();
setInterval(updatePrice, 3000);
})();