Welcome to a quick tutorial and sharing on how to create a countdown timer using pure CSS only. Want to create a countdown timer without any Javascript. Yes, it is possible with modern CSS animations and keyframes – Read on for the example!
ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
TABLE OF CONTENTS
DOWNLOAD & DEMO
Firstly, here is the download link to the example code as promised.
QUICK NOTES
If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.
EXAMPLE CODE DOWNLOAD
Click here to download all the example source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
CSS COUNTDOWN DEMO
This demo is set to loop infinitely for convenience. In the zip file and example below, the animation will end at “pop”.
CSS COUNTDOWN TIMER
All right, let us now get into the details of how the CSS countdown timer works.
PART 1) THE HTML
<div class="cwrap"><div class="cmove">
<div>5</div> <div>4</div>
<div>3</div> <div>2</div>
<div>1</div> <div>POP!</div>
</div></div>
This is kind of confusing, but the basic idea here is:
<div class="cwrap">
A “fixed” outer wrapper.<div class="cmove">
Place the countdown numbers in this inner wrapper, and use CSS animation to shift them upward.
PART 2) SETTING THE FONT
/* (A) FONT & BOX SIZING */
.cwrap, .cwrap * {
font-size: 2em;
font-family: impact, sans-serif;
box-sizing: border-box;
}
The first part of the CSS should be self-explanatory, we are just defining the font size and font family of the countdown timer.
PART 3) INNER & OUTER WRAPPERS
/* (B) OUTER WRAPPER & SLIDES - SAME DIMENSIONS */
.cwrap, .cmove div {
width: 300px; height: 250px;
}
/* (C) OUTER WRAPPER */
.cwrap {
color: #fff;
background: #000;
overflow: hidden; /* hide scrollbars */
}
/* (D) INNER WRAPPER */
.cmove {
position: relative;
bottom: 0%;
}
/* (E) SLIDES - CENTERED */
.cmove div {
display: flex;
align-items: center;
justify-content: center;
}
Next, we deal with the “base foundations” of the widget.
- (B) Set all the “countdown number slides” to the same dimension as the outer wrapper.
- (C) Hide overflow, or there will be an ugly scrollbar.
- (D) Set a relative position on the “inner moving wrapper”, this is required to move the numbers with CSS animation later.
- (E) Cosmetics. Center the number in the middle.
PART 4) COUNTDOWN ANIMATION
/* (F) SLIDE ANIMATION */
@keyframes countdown {
/* (F0) THE IDEA - USE KEYFRAMES TO SHIFT SLIDES *
0% { bottom: 0; } 20% { bottom: 100%; }
40% { bottom: 200%; } 60% { bottom: 300%; }
80% { bottom: 400%; } 100% { bottom: 500%; }
/* (F1) BUT THE ABOVE WILL SHIFT NON-STOP */
/* SO WE ADD PAUSES BETWEEN EACH SLIDE */
0% { bottom: 0; } 16% { bottom: 0; }
20% { bottom: 100%; } 36% { bottom: 100%; }
40% { bottom: 200%; } 56% { bottom: 200%; }
60% { bottom: 300%; } 76% { bottom: 300%; }
80% { bottom: 400%; } 96% { bottom: 400%; }
100% { bottom: 500%; }
}
/* (F2) 5 SLIDES = 5 SECONDS */
.cmove {
animation: countdown linear 5s;
animation-fill-mode: forwards;
}
- (F1) Lastly, we define a set of
@keyframes
to drive the countdown timer. Essentially, usingbottom: PERCENT
to rotate through the numbers. - (F2) Attach the
@keyframes
to the<div class="cmove">
.
EXTRA BITS & LINKS
That’s all for the tutorial, and here is a small section on some extras and links that may be useful to you.
START ON CUE
Yes, this example will begin counting down as soon as the loading is complete. If you want to control when to start the countdown, there are 2 possible ways:
- Using Javascript.
- Change (F2) to a different CSS class. For example,
.cstart { animation: ... }
- Attach the CSS class to the container manually, for example –
<div class="cmove" onclick="this.classList.add('cstart')">
- Change (F2) to a different CSS class. For example,
- Checkbox trick.
- Add a hidden radio button before the move wrapper –
<input type="radio" id="ninja" style="display:none"><div class="cmove">
- Add a label anywhere to toggle the radio button –
<label for="ninja">
- Change (F2) to toggle on checked –
#ninja:checked + .cmove { animation: ... }
- Add a hidden radio button before the move wrapper –
COMPATIBILITY CHECKS
- CSS Keyframes – CanIUse
- CSS Animation – CanIUse
Works on all modern “Grade A” browsers.
LINKS & REFERENCES
- Javascript Countdown Timer – Code Boxx
- Example On CodePen – Pure CSS Countdown
THE END
Thank you for reading, and we have come to the end. I hope that it has helped you to better understand, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!