We’re going to write some code that will animate the hands of a clock around to simulate 12 hours. We’ll be using CSS @keyframes
and a bunch of SVG graphics to complete the animation.
This is what it should look like when it’s done:
A lesson in using CSS keyframe animations to make a clock face with rotating hands.
We’re going to write some code that will animate the hands of a clock around to simulate 12 hours. We’ll be using CSS @keyframes
and a bunch of SVG graphics to complete the animation.
This is what it should look like when it’s done:
Remember the purpose of this lesson is to type the code out yourself—build up that muscle memory in your fingers!
Start the lesson by forking and cloning the animated-clock
repository.
Fork & clone the “animated-clock” repo.
The repository will have some starter files to get you on your way and include requirements for Markbot so you can be sure you’ve completed the lesson.
This includes some starter code that you can get by forking and cloning the repository. You’ll use Markbot to double check everything is done properly.
We’ll need some extra files that are too large to be in a Git repository to complete this lesson.
Download the “animated-clock” files.
If the files are Illustrator (.ai
) files or Photoshop (.psd
) files go ahead and export them following our standard procedures.
The download will include things like images, PSDs, AIs, etc. that we need for the lesson that are too big for Git & GitHub.
After forking and cloning the repository & downloading and exporting the files you should have the following folder structure:
There’s also some HTML & CSS already coded so we can concentrate completely on styling the clock and making it animate.
We’ll start by writing out some HTML for the clock face. The centre piece and the two hands will be <img>
tags, but the clock face will be a background-image
⋮
<body>
<div class="clock-face">
<img class="hand hand-hour" src="images/hand-hour.svg" alt="">
<img class="hand hand-minute" src="images/hand-minute.svg" alt="">
<img class="clock-center" src="images/clock-center.svg" alt="">
</div>
</body>
⋮
There isn’t really anything spectacular in that code—just plain ol’ HTML.
In the browser we should see this—which isn’t much to look at:
Notice that there are two classes here: .hand
and a more specific one. We’re going to save some typing by putting the common CSS on the .hand
class.
Next up we need to style the clock face using background-image
and a few other small things. It makes the most sense to use a background-image
for the clock face for two reasons:
html {
background-color: #000;
}
.clock-face {
height: 300px;
margin: 50px auto;
position: relative;
width: 300px;
background: transparent url("../images/clock-face.svg") no-repeat center center;
}
So we should see this now:
The 50px
margin is just to push the clock downwards from the top a little bit—we’d probably use .pad-top
or something in a real website.
To save some typing we have all the background
properties on one line: color
, image
, repeat
, position
Using position
and some coordinates we can get the hands and the centre piece of the clock in place.
⋮
.clock-center {
bottom: calc(50% - 14px);
left: calc(50% - 14px);
position: absolute;
width: 28px;
}
.hand {
bottom: calc(50% - 8px);
left: calc(50% - 7px);
position: absolute;
width: 14px;
transform-origin: 50% calc(100% - 8px);
}
Refresh it in your browser and you’ll see the hands and the centre piece are nicely aligned.
We know that the centre piece is 28px
wide. So to get it exactly in the centre of the clock face we can set the left
& bottom
coordinates to 50% - 14px
(14px
being half of 28px
).
All these CSS properties are shared with both clock hands, that’s why we’re targeting the .hand
class.
This is definitely a little silly because the black centre peice covers it but I wanted to create the impression that the clock hands weren’t pivoting on their edge, but that they had like a physical “pin” set in the bottom center of the rounded part—so I positioned them in a “realistic” fashion.
The default transform-origin
for an element is the direct centre—that doesn’t make sense for a clock hand. So this will change the anchor point to be placed in my invisible “pin” rotation point for the clock hands.
We’re going to start by animating the minute hand, because that’s the one we can see right now. We’ll need a @keyframes
block and an animation
property targeted at just that single hand.
⋮
.hand-minute {
animation: hand-rotate .5s linear infinite;
}
@keyframes hand-rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
Try it out! You should see the minute hand moving around the clock.
The animation
property is connecting the @keyframes
block with this element. We are specifying the following things:
hand-rotate
is the name we chose for the @keyframes
block..5s
is the time it takes for the hand to fully rotate around the clock.linear
means there is no easing.infinite
means that the animation never stops—it keeps looping.Immediately after the @keyframes
keyword we need to come up with a name for this block, here we are naming these keyframes hand-rotate
At the start of the animation (0%
) the rotation of the hand is 0deg
At the end of the animation the rotation is 360deg
meaning the hand will complete a full rotation around a circle.
Finally we’re going to make the hour hand rotate. This one is really easy because it’s animation is exactly the same as the minute hand—it just takes a longer time to rotate.
⋮
.hand-hour {
animation: hand-rotate 6s linear infinite;
}
That’s it—give it a whirl!
The only difference is that the time is now 6s
. From a clock perspective this allows the minute hand to rotate 12 times, 1 rotation for each hour, while the hour hand only rotates a single time.
Drop the final, coded exercise into Markbot and fix all the errors until Markbot gives you all green (and maybe a little yellow).
After you’ve fixed all the problems, go ahead and submit the assignment. You’ll immediately get your grade.