Bootstrap 5 Countdown Timer
A Bootstrap 5 Countdown Timer component displays a live ticking countdown to a specific date or event, built using a combination of Bootstrap's grid and utility classes alongside a small JavaScript snippet. It's used in marketing contexts to create urgency — driving conversions by showing visitors exactly how much time remains before a deal expires, a product launches, or an event begins.
Primary Class
.countdown-timerCommon Use Cases
- →Flash sale end timers on e-commerce landing pages that reset every 24 hours to maintain urgency without changing the actual deadline
- →Product launch countdowns on pre-launch pages collecting email sign-ups before a SaaS tool goes live
- →Event registration deadlines for webinars, workshops, or conferences showing days, hours, and minutes until early-bird pricing closes
- →Limited-availability offer timers on checkout pages showing time left to claim a discount code before it expires
Variants & Classes
| Variant | Description |
|---|---|
| Countdown Timer Default | Standard countdown timer with Bootstrap's default styling. |
| Countdown Timer Responsive | Responsive variant that adapts to different screen sizes. |
Code Example
<div class="bg-dark text-white py-5">
<div class="container text-center">
<h2 class="fw-bold mb-2">Summer Sale Ends In</h2>
<p class="text-white-50 mb-4">Get 40% off everything before the clock hits zero.</p>
<div class="row justify-content-center g-3" id="countdown">
<div class="col-auto">
<div class="bg-primary rounded-3 px-4 py-3">
<div class="display-4 fw-bold" id="days">02</div>
<div class="small text-uppercase text-white-50 mt-1">Days</div>
</div>
</div>
<div class="col-auto">
<div class="bg-primary rounded-3 px-4 py-3">
<div class="display-4 fw-bold" id="hours">14</div>
<div class="small text-uppercase text-white-50 mt-1">Hours</div>
</div>
</div>
<div class="col-auto">
<div class="bg-primary rounded-3 px-4 py-3">
<div class="display-4 fw-bold" id="minutes">37</div>
<div class="small text-uppercase text-white-50 mt-1">Minutes</div>
</div>
</div>
<div class="col-auto">
<div class="bg-primary rounded-3 px-4 py-3">
<div class="display-4 fw-bold" id="seconds">09</div>
<div class="small text-uppercase text-white-50 mt-1">Seconds</div>
</div>
</div>
</div>
<a href="#shop" class="btn btn-light btn-lg mt-4 px-5">Shop the Sale</a>
</div>
</div>
<script>
const deadline = new Date('2025-09-01T00:00:00').getTime();
function updateCountdown() {
const now = new Date().getTime();
const gap = deadline - now;
if (gap <= 0) {
document.getElementById('countdown').innerHTML = '<p class="text-white">Sale has ended.</p>';
return;
}
document.getElementById('days').textContent = String(Math.floor(gap / 86400000)).padStart(2,'0');
document.getElementById('hours').textContent = String(Math.floor((gap % 86400000) / 3600000)).padStart(2,'0');
document.getElementById('minutes').textContent = String(Math.floor((gap % 3600000) / 60000)).padStart(2,'0');
document.getElementById('seconds').textContent = String(Math.floor((gap % 60000) / 1000)).padStart(2,'0');
}
updateCountdown();
setInterval(updateCountdown, 1000);
</script>Live Examples
Basic Countdown Timer
Canvas Framework Variants
The Canvas template extends Bootstrap 5 with 1,658+ component variants. Generate any of these using Canvas Builder:
- ✓Canvas Builder generated countdown timer with custom colours
- ✓Countdown Timer with interactive states
- ✓Responsive countdown timer for all screen sizes
Best Practices
Set a real, fixed deadline — never fake urgency
Use a hardcoded UTC timestamp as the countdown target. Evergreen 'resets every 24 hours' tactics are easy to detect, erode trust, and increasingly flagged by browser extensions — a genuine deadline converts better long-term.
Pair the timer with a single CTA below it
Place one action-oriented button (e.g. 'Claim Discount' or 'Register Now') directly beneath the countdown blocks — Bootstrap's `mt-4` utility keeps the spacing tight without cluttering the visual hierarchy.
Use `padStart(2,'0')` for consistent digit width
Without zero-padding, single-digit values like '9' cause the layout to jump as numbers change — `padStart(2,'0')` keeps each block a fixed two-character width and prevents layout shift.
Handle the expired state explicitly
Always check `if (gap <= 0)` and replace the timer with a meaningful message or redirect — leaving a timer stuck at 00:00:00 undermines credibility and confuses visitors who land on the page after the deadline.