Simple Countdown Timer Using JavaScript
Tags: javascript, css, tutorial, beginners
Published: 2022-09-20 18:23:48

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.

## View This On YouTube
{% youtube WGekurbM1Hg %}

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

## Our HTML

```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

```js
// 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:

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

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:

```js
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:

```html
<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>
```

```js
// 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)_.

```css
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. 

Read more articles on [DevDrawer](https://thedevdrawer.com)