Animated clock

A lesson in using CSS keyframe animations to make a clock face with rotating hands.

Goal

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:

  1. Type it, type it real good

    Remember the purpose of this lesson is to type the code out yourself—build up that muscle memory in your fingers!

Fork & clone

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.

  1. Fork, clone & Markbot

    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.

Download assets

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.

  1. Downloads

    The download will include things like images, PSDs, AIs, etc. that we need for the lesson that are too big for Git & GitHub.

1 Project files

After forking and cloning the repository & downloading and exporting the files you should have the following folder structure:

  1. animated-clock
  2. images Export these from Illustrator
  3. clock-center.svg
  4. clock-face.svg
  5. hand-hour.svg
  6. hand-minute.svg
  7. css
  8. main.css
  9. modules.css
  10. index.html

There’s also some HTML & CSS already coded so we can concentrate completely on styling the clock and making it animate.

2 Write some HTML

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:

  1. Lines E–F

    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.

3 Style the clock face

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:

  1. It doesn’t animate, so we don’t really need to access it.
  2. The clock pieces, like the hands, are in front of it. Because the clock face is a background image it’s much less work to get the bits in front.
*,
*::before,
*::after {
  box-sizing: inherit;
}

.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:

  1. Line I

    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.

  2. Line M

    To save some typing we have all the background properties on one line: color, image, repeat, position

4 Style the hands

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.

  1. Lines C–D

    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).

  2. Line I

    All these CSS properties are shared with both clock hands, that’s why we’re targeting the .hand class.

  3. Lines J–K

    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.

  4. Line O

    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.

5 Animate the minute hand

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.

  1. Line C

    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.
  2. Line F

    Immediately after the @keyframes keyword we need to come up with a name for this block, here we are naming these keyframes hand-rotate

  3. Lines H–J

    At the start of the animation (0%) the rotation of the hand is 0deg

  4. Lines L–N

    At the end of the animation the rotation is 360deg meaning the hand will complete a full rotation around a circle.

6 Animate the hour hand

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!

  1. Line C

    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 it into Markbot & submit

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.

  1. Submit

    Whenever you’ve passed all Markbot’s specific tests go ahead and submit this lesson for marks.