Your Current Language Is:

How To Create A Countdown Clock With CSS3

By

I had my first opportunity to code some CSS3 animations for November’s CSSOff, which is “a competition for front-end developers to show off their skills in a no holds barred display of CSS and markup skills.”

Part of the competition centered around creating a countdown clock. In an attempt to break out from the pack, I decided to keep it CSS-only, which I found out later was fairly unique. Post-competition, I saw others’ completed challenges and similar clocks used Javascript to create it.

My goal was to stay as semantic as possible and to learn more about animations and transitions using CSS. Below is the HTML markup for the clock and the explanation for my methods.

<div class="clock">
	<ol class="tens">
		<li>6</li>
		<li>5</li>
		<li>4</li>
		<li>3</li>
		<li>2</li>
		<li>1</li>
	</ol>
	<ol class="digits">
		<li>0</li>
		<li>9</li>
		<li>8</li>
		<li>7</li>
		<li>6</li>
		<li>5</li>
		<li>4</li>
		<li>3</li>
		<li>2</li>
		<li>1</li>
	</ol>
	<ol class="done">
		<li>0</li>
	</ol>
</div>

There are three ordered lists that the countdown walks through. I could probably take this one step further and automate the numbers using counter-increments, but for this example, I included all numbers in the HTML. The first ordered list contains all of the numbers for the tens decimal place, the second contains the ones, and the last contains the zero we’ll flash repeatedly to indicate that the countdown has completed.

First, I had to figure out how to rotate through each set of numbers. With the exception of the initial “6″, our tens would need to change every ten seconds. That first “6″ which would only flash for one second at the beginning of the countdown, which we’ll get to in a second.

.tens li:nth-of-type(2) {
	-webkit-animation: tencount 60s ease-in-out 1s 1;
	-moz-animation:	   tencount 60s ease-in-out 1s 1; 
	-o-animation: 	   tencount 60s ease-in-out 1s 1; 
	-ms-animation:	   tencount 60s ease-in-out 1s 1; 
}
.tens li:nth-of-type(3) {
	-webkit-animation: tencount 60s ease-in-out 11s 1;
	-moz-animation:	   tencount 60s ease-in-out 11s 1; 
	-o-animation: 	   tencount 60s ease-in-out 11s 1; 
	-ms-animation:	   tencount 60s ease-in-out 11s 1; 
}
...

… and so on and so forth for each list item in the first ordered list. The above says that the element will use the “tencount” animation for 60 seconds, an “ease-in-out” timing function for the keyframes’ animation that will start at a particular second of the animation (1 seconds, 11 seconds, etc.) and only animate once. Here are the keyframes for my “tencount” animation:

@keyframes tencount {
	0% { opacity: 1 }
	16.6% { opacity: 1 }
	16.7% { opacity: 0 }
	100% { opacity: 0 }
}

At the beginning of the animation, the digit will be at 100% opacity. At 16.6% (10 seconds), it will remain at 100% opacity, but a moment later will be invisible through the end of the animation (60 seconds). The only odd part of the CSS animations for this first ordered list is that the first digit “6″ only gets shown for one second, so I used our next animation style “digitcount” to show it for one second.

.tens li:nth-of-type(1) {
 	-webkit-animation: digitcount 10s ease-in-out 0s 1;
	-moz-animation:	   digitcount 10s ease-in-out 0s 1; 
	-o-animation: 	   digitcount 10s ease-in-out 0s 1; 
	-ms-animation:	   digitcount 10s ease-in-out 0s 1; 
}

I use the same animation for the next ordered list, but changed the number of times the animation will occur (6 instead of 1).

.digits li:nth-of-type(1) {
	-webkit-animation: digitcount 10s ease-in-out 0s 6; 
	-moz-animation:	   digitcount 10s ease-in-out 0s 6; 
	-o-animation: 	   digitcount 10s ease-in-out 0s 6; 
	-ms-animation:	   digitcount 10s ease-in-out 0s 6; 
}
.digits li:nth-of-type(2) {
	-webkit-animation: digitcount 10s ease-in-out 1s 6; 
	-moz-animation:	   digitcount 10s ease-in-out 1s 6; 
	-o-animation: 	   digitcount 10s ease-in-out 1s 6; 
	-ms-animation:	   digitcount 10s ease-in-out 1s 6; 
}
...

… and so on for each item in this ordered list. These list items will be repeating over and over until all of the tens have run out. The “digitcount” CSS animation has a similar set of keyframes to the “tencount” animation, but “digitcount” is only 10 seconds long instead of 60, so we change opacity at the 1 second mark (10% of the total animation time).

@keyframes digitcount {
	0% { opacity: 1 }
	9.9% { opacity: 1 }
	10% { opacity: 0 }
	100% { opacity: 0 }
}

This leaves us with one more ordered list to animate: the zero that flashes when the countdown ends!

.done li {
	-webkit-animation: zero 1s ease-in-out 60s infinite; 
	-moz-animation:	   zero 1s ease-in-out 60s infinite; 
	-o-animation:	   zero 1s ease-in-out 60s infinite; 
	-ms-animation:	   zero 1s ease-in-out 60s infinite; 
}

@keyframes zero {
	0% { opacity: 1 }
	90% { opacity: 1 }
	100% { opacity: 0 }
}

We’re pausing 60 seconds before showing this flashing zero, but then repeating this one-second animation infinitely. Here’s the full effect when you apply CSS positioning to each list (and you’re using a modern browser):

  1. 6
  2. 5
  3. 4
  4. 3
  5. 2
  6. 1
  1. 0
  2. 9
  3. 8
  4. 7
  5. 6
  6. 5
  7. 4
  8. 3
  9. 2
  10. 1
  1. 0

I’m eager to hear if there are more semantic ways of doing this with a CSS-only solution. I’m pretty happy with the results, which you can see by scrolling to the bottom of this page under ‘Be A Contestant’.

Lara Swanson is the lead front-end web developer for Dyn. You can follow her thoughts on coding semantically, nitpicking page load time, and the importance of baking for coworkers on Twitter.

Related Posts