## Creating a Clock with the New CSS sin() and cos() Trigonometry Functions

Here’s what I have in mind. Again, it’s only supported in Firefox and Safari at the moment:

So, it’s not exactly like words forming a circular shape, but we are placing text characters along the circle to form a clock face. Here’s some markup we can use to kick things off:

Next, here are some super basic styles for the `.clock-face`

container. I decided to use the `<time>`

tag with a `datetime`

attribute.

It looks like some sort of modern art experiment, right? Let’s introduce a new variable, `--_r`

, to store the circle’s **radius**, which is equal to half of the circle’s width. This way, if the width (`--_w`

) changes, the radius value (`--_r`

) will also update — thanks to another CSS math function, `calc()`

:

Now, a bit of math. A circle is 360 degrees. We have 12 labels on our clock, so want to place the numbers every 30 degrees (`360 / 12`

). In math-land, a circle begins at 3 o’clock, so noon is actually **minus 90 degrees** from that, which is 270 degrees (`360 - 90`

).

Let’s add another variable, `--_d`

, that we can use to set a **degree** value for each number on the clock face. We’re going to increment the values by 30 degrees to complete our circle:

OK, now’s the time to get our hands dirty with the `sin()`

and `cos()`

functions! What we want to do is use them to get the X and Y coordinates for each number so we can place them properly around the clock face.

The formula for the X coordinate is `radius + (radius * cos(degree))`

. Let’s plug that into our new `--_x`

variable:

The formula for the Y coordinate is `radius + (radius * sin(degree))`

. We have what we need to calculate that:

There are a few housekeeping things we need to do to set up the numbers, so let’s put some basic styling on them to make sure they are absolutely positioned and placed with our coordinates:

Notice `--_sz`

, which we’ll use for the `width`

and `height`

of the numbers in a moment. Let’s see what we have so far.

This definitely looks more like a clock! See how the top-left corner of each number is positioned at the correct place around the circle? We need to “shrink” the radius when calculating the positions for each number. We can *deduct* the size of a number (`--_sz`

) from the size of the circle (`--_w`

), before we calculate the radius:

Much better! Let’s change the colors, so it looks more elegant:

We could stop right here! We accomplished the goal of placing text around a circle, right? But what’s a clock without arms to show hours, minutes, and seconds?

Let’s use a single CSS animation for that. First, let’s add three more elements to our markup,

Then some common markup for all three arms. Again, most of this is just make sure the arms are absolutely positioned and placed accordingly:

We’ll use the **same animation** for all three arms:

The **seconds arm** is *almost the same* as the minutes arm, but the duration is 60 seconds instead of 60 minutes:

Let’s update the properties we created in the common styles:

What if we want to start at the current time? We need a little bit of JavaScript:

In the CSS, we need to add the `animation-delay`

as well:

**Just one more thing.** Using CSS `@supports`

and the properties we’ve already created, we can provide a fallback to browsers that do not supprt `sin()`

and `cos()`

. (Thank you, Temani Afif!):

And, voilà! Our clock is done! Here’s the final demo one more time. Again, it’s only supported in Firefox and Safari at the moment.

Just messing around here, but we can quickly turn our clock into a circular image gallery by replacing the `<time>`

tags with `<img>`

then updating the width (`--_w`

) and radius (`--_r`

) values:

Let’s try one more. I mentioned earlier how the clock looked kind of like a modern art experiment. We can lean into that and re-create a pattern I saw on a poster (that I unfortunately didn’t buy) in an art gallery the other day. As I recall, it was called “Moon” and consisted of a bunch of dots forming a circle.

We’ll use an unordered list this time since the circles don’t follow a particular order. We’re not even going to put all the list items in the markup. Instead, let’s inject them with JavaScript and add a few controls we can use to manipulate the final result.

The controls are range inputs (`<input type="range">)`

which we’ll wrap in a `<form>`

and listen for the `input`

event.

We’ll run this method on “input”, which will create a bunch of `<li>`

elements with the degree (`--_d`

) variable we used earlier applied to each one. We can also repurpose our radius variable (`--_r`

) .

I also want the dots to be different colors. So, let’s randomize (well, not *completely* randomized) the HSL color value for each list item and store it as a new CSS variable, `--_bgc`

:

The `random()`

method picks a value within a defined range of numbers:

And that’s it. We use JavaScript to render the markup, but as soon as it’s rendered, we don’t really need it. The `sin()`

and `cos()`

functions help us position all the dots in the right spots.

Placing things around a circle is a pretty basic example to demonstrate the powers of trigonometry functions like `sin()`

and `cos()`

. But it’s *really* cool that we are getting modern CSS features that provide new solutions for old workarounds I’m sure we’ll see way more interesting, complex, and creative use cases, especially as browser support comes to Chrome and Edge.

If you need help creating a digital marketing strategy for your business, don’t hesitate to contact one of Digidude’s consultants.

### Post a Comment

You must be logged in to post a comment.