Word Clock
8 Feb 2023 · 📖 in 9 minutes It's quarter to three (I wrote another clock)Given the recent article by Alex Russell on the state of JS in 2023 (The Market for Lemons - well worth a read) and the so-called "lost decade" I felt the urge to revisit Web Components again.
The Plan
The main aim of my little project is to try building something small using the latest and greatest APIs available to us in the browser (relying heavily on the contents of Using custom elements and the excellent Introduction to Web Components).
This means vanilla HTML, CSS and a sprinkling of JavaScript.
Ideally I wanted to have as much of my UI described in HTML (using <template>
) and then rely on JS to glue it all together.
I also like the idea of the shadow DOM and what that can do for isolating styles from the rest of the page so I also want to build something that I could drop into this blog easily.
Drum Roll please... 🥁
I present, the Word Clock:
(don't worry, I won't be offended if you don't watch this for 5 minutes to check it does, in fact, tell the time)
The above is the page rendering my new Custom HTML Element word-clock
and if you view source on this page you should see a bunch of additional HTML that defines various bits about the clock.
I also wrote another little clock once, you can read about that here
Shallow Dive?
A small bit of navel gazing for anyone interested, I would recommend "view source" though - I find it far better to read code than to have people explain it to me.
Style AND Substance (Structure)
As described in the plan the main "UI" (not that it's much more than a <p>
tag and some <span>
tags) is described in a <template>
with the id "word-clock-template"
. This allows me to outline the structure and style using plain old HTML and CSS.
The <template>
also allows me to define <slots>
which can be used to configure the UI "from the outside" - that is, the page that's actually rendering the custom component.
So it's possible to change the words on the clock via some named elements:
<word-clock>
<span slot="ten">10<span>
</word-clock>
The above would change the "ten" to display "10".. wait, why am I explaining this... here's a demo where I've swapped each word for its Roman numeral:
There's potential here for something more interesting involving translations, whereby a non-english implementation could substitute the various phrases for the equivalent. However, the structure and layout of the text would also need some tweaks as the grammar isn't quite the same.
Alternative layouts could be achieved by creating different templates e.g."word-clock-spanish"
and then passing these as attributes to the word-clock
component like:
<word-clock template="word-clock-spanish" />
This decoupling from the structure, style and logic allows for great flexibility when iterating.
So, how's it tick?
The bulk of the "logic" is held in the WordClock
class that extends the HTMLElement
and creates the custom component (with the call to register the class via customElements.define
).
The way this is implemented relies of updating an active
CSS class which can then highlight / animate portions of the "clock face".
The time is broken down to simple switch/case
statements building off the idea the smallest portion of time is 5 minute increments, allowing for 12 different cases to describe 5, 10, quarter, half to and past.
Similarly an aria label is built via the same switch/case
statement.
I encourage you to visit the Word Clock and have a play. There's also a little test I was doing with Spanish that didn't pan out. As I mentioned above the structure / word order is subtly different e.g. with "25 minutes to" the order of sentance would be swapped in Spanish "Son las siete menos veinticinco" as opposed to what the the naive spanish word clock would try "son las viente cinco minutos a siete".
There's also fun to be had with "half past", as there's some languages that take "half past six" to mean something more like 17:30 "half way to six" e.g. Afrikaans, German and others I'm sure. This has piqued my interest as it would be nice to be able to take user language preference into consideration when rendering the clock. There may be more to this story.
That's a wrap, for now.
This was a fun little exercise in what the web / browser can do. I believe there's potential here and for the first time in a long while I wrote HTML directly into a .html
file and then viewed it in a browser, no build tools, no JS / TS / Babel transpilation.
None of what I've done here is particularly novel but I am guilty of having ploughed ahead with React without taking a second to look around and see what else is there. These days the Browser APIs are in decent shape, and getting better each month.
I also hope that the Webkit-only rule on iOS will soon be lifted further opening the door for browsers to realise their full potential. Perhaps Web Components will be part of that future too?