15 CSS Number Counter Animations
Product Launch Countdown
Ultra-clean white layout with massive Rajdhani numerals ticking down days:hours:minutes:seconds in real time. Colons blink, minimal diagonal background shapes add depth. Drop-in for pre-launch landing pages and feature release announcements.
Product Launch Countdown the 3rd of 15 designs in the 15 CSS Number Counter Animations 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="cnc-cd">
<div class="cnc-cd-scene">
<div class="cnc-cd-inner">
<div class="cnc-cd-pre-label">Something new is coming</div>
<div class="cnc-cd-units">
<div class="cnc-cd-unit"><div class="cnc-cd-num-block" data-cd="d">00</div><div class="cnc-cd-unit-label">Days</div></div>
<div class="cnc-cd-colon">:</div>
<div class="cnc-cd-unit"><div class="cnc-cd-num-block" data-cd="h">00</div><div class="cnc-cd-unit-label">Hours</div></div>
<div class="cnc-cd-colon">:</div>
<div class="cnc-cd-unit"><div class="cnc-cd-num-block" data-cd="m">00</div><div class="cnc-cd-unit-label">Min</div></div>
<div class="cnc-cd-colon">:</div>
<div class="cnc-cd-unit"><div class="cnc-cd-num-block" data-cd="s">00</div><div class="cnc-cd-unit-label">Sec</div></div>
</div>
<div class="cnc-cd-tagline">Until <strong>Forma Studio 3.0</strong> is live for everyone.</div>
<button class="cnc-cd-btn" type="button">Notify Me</button>
</div>
</div>
</div> .cnc-cd { display: grid; place-items: center; padding: 32px 16px; background: #fff; overflow: hidden; font-family: 'Quicksand', sans-serif; }
.cnc-cd *, .cnc-cd *::before, .cnc-cd *::after { box-sizing: border-box; }
.cnc-cd-scene { position: relative; text-align: center; padding: 60px 40px; width: 560px; }
.cnc-cd-scene::before { content: ''; position: absolute; top: -40px; right: -80px; width: 320px; height: 320px; background: #f0f0f0; transform: rotate(25deg); border-radius: 40px; z-index: 0; }
.cnc-cd-scene::after { content: ''; position: absolute; bottom: -60px; left: -60px; width: 260px; height: 260px; background: #f6f6f6; transform: rotate(15deg); border-radius: 40px; z-index: 0; }
.cnc-cd-inner { position: relative; z-index: 1; }
.cnc-cd-pre-label { font-size: 10px; letter-spacing: 6px; text-transform: uppercase; color: #bbb; font-weight: 400; margin-bottom: 48px; opacity: 0; animation: cnc-cd-rise 0.5s ease 0.1s forwards; }
.cnc-cd-units { display: flex; justify-content: center; align-items: flex-start; gap: 6px; margin-bottom: 10px; }
.cnc-cd-unit { display: flex; flex-direction: column; align-items: center; opacity: 0; animation: cnc-cd-rise 0.6s cubic-bezier(0.22,1,0.36,1) forwards; }
.cnc-cd-unit:nth-child(1) { animation-delay: 0.2s; }
.cnc-cd-unit:nth-child(2) { animation-delay: 0.3s; }
.cnc-cd-unit:nth-child(3) { animation-delay: 0.4s; }
.cnc-cd-unit:nth-child(4) { animation-delay: 0.5s; }
.cnc-cd-num-block { font-family: 'Rajdhani', sans-serif; font-size: clamp(72px, 14vw, 110px); font-weight: 700; color: #111; line-height: 0.9; letter-spacing: -4px; min-width: 2ch; text-align: center; position: relative; }
.cnc-cd-num-block::after { content: ''; position: absolute; bottom: -6px; left: 10%; right: 10%; height: 2px; background: #111; transform: scaleX(0); transform-origin: left; animation: cnc-cd-lineIn 0.5s ease forwards; }
.cnc-cd-unit:nth-child(1) .cnc-cd-num-block::after { animation-delay: 0.6s; }
.cnc-cd-unit:nth-child(2) .cnc-cd-num-block::after { animation-delay: 0.75s; }
.cnc-cd-unit:nth-child(3) .cnc-cd-num-block::after { animation-delay: 0.9s; }
.cnc-cd-unit:nth-child(4) .cnc-cd-num-block::after { animation-delay: 1.05s; }
@keyframes cnc-cd-lineIn { to { transform: scaleX(1); } }
.cnc-cd-colon { font-family: 'Rajdhani', sans-serif; font-size: clamp(48px, 10vw, 80px); font-weight: 300; color: #ddd; line-height: 0.9; padding-top: 4px; opacity: 0; animation: cnc-cd-rise 0.4s ease 0.25s forwards, cnc-cd-blink 1s step-end infinite 1.5s; }
@keyframes cnc-cd-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.15; } }
.cnc-cd-unit-label { font-size: 9px; letter-spacing: 4px; text-transform: uppercase; color: #ccc; font-weight: 400; margin-top: 18px; }
.cnc-cd-tagline { margin-top: 52px; font-size: 13px; color: #aaa; font-weight: 300; letter-spacing: 0.5px; opacity: 0; animation: cnc-cd-rise 0.6s ease 0.8s forwards; }
.cnc-cd-tagline strong { color: #111; font-weight: 600; }
.cnc-cd-btn { display: inline-block; margin-top: 32px; padding: 14px 36px; background: #111; color: #fff; font-family: 'Quicksand', sans-serif; font-size: 12px; font-weight: 600; letter-spacing: 3px; text-transform: uppercase; border: none; cursor: pointer; border-radius: 0; opacity: 0; animation: cnc-cd-rise 0.6s ease 1.0s forwards; position: relative; overflow: hidden; transition: background 0.2s; }
.cnc-cd-btn::after { content: ''; position: absolute; inset: 0; background: rgba(255,255,255,0.1); transform: translateX(-100%); transition: transform 0.3s ease; }
.cnc-cd-btn:hover::after { transform: translateX(0); }
@keyframes cnc-cd-rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) {
.cnc-cd-pre-label, .cnc-cd-unit, .cnc-cd-colon, .cnc-cd-tagline, .cnc-cd-btn, .cnc-cd-num-block::after { animation: none; opacity: 1; transform: none; }
} (function () {
var root = document.querySelector('.cnc-cd');
if (!root) return;
var target = new Date();
target.setDate(target.getDate() + 14);
target.setHours(target.getHours() + 6);
target.setMinutes(target.getMinutes() + 42);
function pad(n) { return String(Math.max(0, n)).padStart(2, '0'); }
var slots = {
d: root.querySelector('[data-cd="d"]'),
h: root.querySelector('[data-cd="h"]'),
m: root.querySelector('[data-cd="m"]'),
s: root.querySelector('[data-cd="s"]'),
};
function update() {
var diff = Math.max(0, target - Date.now());
slots.d.textContent = pad(Math.floor(diff / 86400000));
slots.h.textContent = pad(Math.floor((diff % 86400000) / 3600000));
slots.m.textContent = pad(Math.floor((diff % 3600000) / 60000));
slots.s.textContent = pad(Math.floor((diff % 60000) / 1000));
}
update();
setInterval(update, 1000);
})();