Create a pure CSS clock with SVG.

John O. Paul
The Andela Way
Published in
5 min readApr 27, 2018

Recently I decided to learn how to write SVG (Scalable Vector Graphics) by hand, as well as SVG animations. I have been using CSS for quite some time but I hadn’t used the steps animation timing function before. It’s basically a function that transitions elements step by step, for the duration of the animation. Here is a pen I created that illustrates how the steps function works.

In this tutorial, we shall create this pure CSS clock. This tutorial is divided into two sections:

  • Section 1 — Creating a static clock.
  • Section 2 — Making the clock work.

Prerequisites

Section 1 — Creating a static clock.

First, Let’s create an outline of the shape of the clock. It’s a simple circle with a white fill and a black stroke.

HTML

The viewBox property of the SVG specifies the x, y, width and height properties respectfully. The radius of the circle is set to19 so that it can fit into the viewBox.

<svg viewBox="0 0 40 40">
<circle cx="20" cy="20" r="19" />
</svg>

CSS

Give the background a light gray color and style the SVG element.

html {
background: #dedede;
}
svg {
width: 400px;
fill: white;
stroke: black;
stroke-width: 1;
stroke-linecap: round;
}

Add 12 marks to indicate the hours on a clock.

HTML

The <g> tag groups the line elements so that, later we can move them at once using CSS transforms. Note that the lines are 12 in total (one for each hour) and have the same coordinates. The <g> element is by default positioned at (0, 0) — the top-left of the viewBox. This is true for all SVG elements.

The <line> elements have similar values of x1, y1, x2 and y2 so that they are of the same height.

CSS

Move <g> element to the center and rotate the lines in intervals of 30 degrees to make them equally spaced around the clock. Let’s also make the 3, 6, 9 and 12 hour marks thicker than the rest by setting theirstroke-width to 0.5 and for the rest of the hands to 0.2.

Let’s add the moving hands and a pin that holds them in place.

HTML

The order of these elements matters. It affects their z-index. Elements that come later in the DOM appear above those that come before them.

CSS

Move the hands of the clock to the center and give them different values of stroke-width to distinguish them.

This is the output of the code we have written so far.

From the image above, you can see that the hands are pointing at the 3 O’clock mark (at a rotate(0deg)). Let’s move the hands to the 12 O’clock mark by rotating the entire SVG by -90deg (-ve degrees rotate anti-clockwise).

CSS

Add the following CSS properties to the svg element to make the hands point to the 12 O’clock mark.

svg {
...
transform: rotate(-90deg);
}

Add some text (for branding purposes) that says, “#TIA” — This is Andela.

HTML

Add the following mark up before the line elements that draw the hands to make it appear below the hands.

<text x="0" y="0" class="tiaText">#TIA</text>

CSS

Position and style the text above.

.tiaText {
font-size: 1px;
font-family: sans-serif;
transform: translate(14px, 19px) rotate(90deg);
fill: #dfdfdf;
stroke: none;
}

This is what your clock should look like if everything is done right. :)

What’s a clock that doesn’t tick? — A dead clock. Let’s make ours work.

Section 2 — Making the clock work.

In order for us to pull off this job, we’re going to employ CSS variables.

Add some CSS variables to reference the time when the page loads. Add the following CSS variables to the svg element’s selector.

svg {
...
--start-seconds: 57;
--start-minutes: 45;
--start-hours: 11;
}

Make the hands correctly indicate the time set above.

CSS

Let’s use CSS transforms to position the hands to the center and rotate them to indicate the appropriate seconds, minutes, or hours set above.

Formula: (Number of seconds/minutes) * 6degrees = rotation of the respective hand for both the seconds and minutes hands.

The clock can only indicate 12 hours so we multiply the number of hours by 30degrees to compute the rotation of the hour hand.

CSS

To make the seconds hand work, we shall define an animation called rotateSecondsHand and use it on the seconds hand (.seconds). The animation timing function is steps(60).

To make the minute hand work, we shall define an animation called rotateMinuteHand and use it on the minute hand (.minute).

CSS

The animation timing function is steps(60). We need to set the animation-delay to a negative value based on the value of --start-seconds. We do this to “forward” the animation, so that the minute hand moves whenever the seconds hand reaches the 12 O’clock mark.

Finally, let’s make the hour hand work. Note that for the hour hand (.hour), animation-delay is dependent on --start-seconds and --start-minutes.

CSS

Here the animation delay is dependent on the values of --start--seconds & --start-minutes.

How to test the clock.

  • To test the minute hand, set--start--seconds:59, --start-minutes:59 and --start-hours:11. The minute hand should move one step with the seconds hand and stop. After that, the minute hand should move whenever the seconds hand reaches the 12 hour mark.
  • To test the hour hand, set--start--seconds:30, --start-minutes:30 and --start-hours:11 . The hour hand should be midway between the 11 and 12 O’clock marks.

Final thoughts

Until CSS can enable us to tell time, we need JavaScript to set the correct time. The accuracy of this clock will depend on that of your device’s time. Here is the JavaScript code that does the job.

This is still a pure CSS clock because it’s functionality is completely in written CSS.

Thanks for making it to the end of the tutorial. If you feel I have left out some explanation(s), feel free to engage me in a discussion via the comments.

--

--