Simple Countdown Timer Using JavaScript

TheDevDrawer
5 min readSep 20, 2022

One of the standard tools you need to know how to do in JavaScript is…how to manipulate time. To demonstrate this, we will build a countdown timer using vanilla JavaScript and CSS.

This is a simple project, but one that shows you how to manipulate time in JS, customize attributes in CSS, and finally add custom parameters to your JS class.

https://www.youtube.com/watch?v=WGekurbM1Hg

File Structure

index.html
/sass
style.scss
/js
init.js
countdown.js
/css (generated by Sass)
style.css
style.min.css

Our HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Countdown Clocks</title>
<link rel="stylesheet" href="/css/style.min.css">
</head>
<body>
<h2>Countdown Clock 1</h2>
<div class="clock" id="clock1">
<div data-value="days"></div>
<div data-value="hours"></div>
<div data-value="minutes"></div>
<div data-value="seconds"></div>
</div>
<script src="/js/countdown.js"></script>
<script src="/js/init.js"></script>
</body>
</html>

Now that we have the basic HTML structure down, we can create the JS class that adds data. Notice we are using data-value so we don't need to add a string in the HTML there, we will modify that will CSS.

Our Countdown JS Class

// class to create a countdown timer
class CountdownTimer {
// setup timer values
constructor({ selector, targetDate, backgroundColor = null, foregroundColor = null }) {
this.selector = selector;
this.targetDate = targetDate;
this.backgroundColor = backgroundColor;
this.foregroundColor = foregroundColor;
// grab divs on frontend using supplied selector ID
this.refs = {
days: document.querySelector(`${this.selector} [data-value="days"]`),
hours: document.querySelector(`${this.selector} [data-value="hours"]`),
mins: document.querySelector(`${this.selector} [data-value="minutes"]`),
secs: document.querySelector(`${this.selector} [data-value="seconds"]`),
};
}
getTimeRemaining(endtime) {
const total = Date.parse(endtime) - Date.parse(new Date());
const days = Math.floor(total / (1000 * 60 * 60 * 24));
const hours = Math.floor((total / (1000 * 60 * 60)) % 24);
const mins = Math.floor((total / 1000 / 60) % 60);
const secs = Math.floor((total / 1000) % 60);
return {
total,
days,
hours,
mins,
secs,
};
}
updateTimer({ days, hours, mins, secs }) {
this.refs.days.textContent = days;
this.refs.hours.textContent = hours;
this.refs.mins.textContent = mins;
this.refs.secs.textContent = secs;
}
updateColors() {
if (this.backgroundColor != null) {
this.refs.days.style.background = this.backgroundColor;
this.refs.hours.style.background = this.backgroundColor;
this.refs.mins.style.background = this.backgroundColor;
this.refs.secs.style.background = this.backgroundColor;
}
if (this.foregroundColor != null) {
this.refs.days.style.color = this.foregroundColor;
this.refs.hours.style.color = this.foregroundColor;
this.refs.mins.style.color = this.foregroundColor;
this.refs.secs.style.color = this.foregroundColor;
}
}
startTimer() {
const timer = this.getTimeRemaining(this.targetDate);
this.updateTimer(timer);
this.updateColors();
setInterval(() => {
const timer = this.getTimeRemaining(this.targetDate);
this.updateTimer(timer);
}, 1000);
}
}

This class will control the div and data-values we need to replace. We create this as a class so we can simply add a few lines of code to add the countdown on any page through our init.js file.

This class takes the selector, the targetDate, and optionally a backgroundColor and foregroundColor. We will pass these values when we call the class.

Calling Our Class

In your init.js file, you can call the countdown class using something like this:

const timer = new CountdownTimer({
selector: "#clock1",
targetDate: new Date("September, 21 2022 18:00:00"),
});
timer.startTimer();

That code will initialize our class and start a countdown to the date we provided. You can also add a background and foreground color to make it a little more custom. They are not required but it would look something like this:

const timer = new CountdownTimer({
selector: "#clock1",
targetDate: new Date("September, 21 2022 18:00:00"),
backgroundColor: "rgba(0,0,0,.15)",
foregroundColor: "rgba(0,0,0,.50)",
});
timer.startTimer();

You must use both background and foreground colors if you customize one or the other. We have it set up for a null value, but in the end, if you use one, you must use the other.

It is that easy. Now that you have your class set up, you can add your countdown to any div you want. You can also add multiple countdowns on one page. For example:

<h2>Countdown Clock 1</h2>
<div class="clock" id="clock1">
<div data-value="days"></div>
<div data-value="hours"></div>
<div data-value="minutes"></div>
<div data-value="seconds"></div>
</div>
<h2>Countdown Clock 2</h2>
<div class="clock" id="clock2">
<div data-value="days"></div>
<div data-value="hours"></div>
<div data-value="minutes"></div>
<div data-value="seconds"></div>
</div>
// setup timer with set textual date in the future
const timer1 = new CountdownTimer({
selector: "#clock1",
targetDate: new Date("September, 21 2022 18:00:00"),
});
timer1.startTimer();// setup timer with date set in the future
const timer2 = new CountdownTimer({
selector: "#clock2",
targetDate: new Date("September, 21 2022 18:00:00"),
backgroundColor: "rgba(0,0,0,.15)",
foregroundColor: "rgba(0,0,0,.50)",
});
timer2.startTimer();

Note In order to use this class on multiple divs, you must pass a unique selector that matches the div ID. In this case, we are using #clock1 and #clock2 that matches our div IDs.

Our Countdown Styles

This part is pretty standard if you have ever used CSS or Sass. Note in the Sass, we are customizing the countdown divs using their data-value attribute. This is where we add the text for our div (Days, Hours, Mins, Secs).

body {
background-color: #38a4ef;
color:#fff;
font-size:16px;
text-align:center;
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
}
.clock {
display:block;
margin: 0 auto;
max-width:80%;
div {
background-color:rgba(255,255,255,.25);
color:#fff;
display:inline-block;
padding:2rem;
margin: 0 1rem;
font-size:2.5rem;
width: calc(10% - 2rem);
text-align:center;
font-weight:bold;
border-radius:5%;
&[data-value*="days"]:after, &[data-value*="hours"]:after, &[data-value*="minutes"]:after, &[data-value*="seconds"]:after {
display:block;
font-size:.75rem;
margin-top:.25rem;
font-weight: 300;
}
&[data-value*="days"]:after {
content:"Days"
}
&[data-value*="hours"]:after {
content:"Hours"
}
&[data-value*="minutes"]:after {
content:"Minutes"
}
&[data-value*="seconds"]:after {
content:"Seconds"
}
}
}
@media screen and (max-width: 820px) {
.clock {
max-width:90%;
div {
width:calc(15% - 2rem)
}
}
}
@media screen and (max-width: 767px) {
.clock {
max-width:100%;
div {
width:calc(30% - 4rem);
margin:.5rem;
padding: .5rem;
font-size:1rem;
&[data-value*="days"]:after, &[data-value*="hours"]:after, &[data-value*="minutes"]:after, &[data-value*="seconds"]:after {
font-size:.5rem;
}
}
}
}

We are simply using the :after CSS selector to add the words to the div. This prevents us from having to edit it each time we place it on a page.

I have also added the responsive media queries to our Sass stylesheet so it should work on tablets and mobile phones.

Conclusion

There you have it, a vanilla JavaScript countdown timer. It is a simple project, yet goes over some pretty cool things you can do with JS and CSS. I hope it helps in your future projects.

--

--

TheDevDrawer
TheDevDrawer

Written by TheDevDrawer

Join me as I discuss programming in a way that can help you get started. Created based on a need I have had. Let’s get started.

No responses yet