Super Clock Part 2

A super clock in PHP, jQuery and CSS3

EXPERIMENTAL
Elvis Salaris

A TMI Super Clock experiment in PHP, jQuery and CSS

This is Part 2 of my super clock post, if you want to see the Math behind it you'll need to go fetch it in Part 1. If you already did that, please remember to take a break every 4 hours of screen-time. The repo is available on github.

This mini-app is built on a small PHP calculator (also fetching some Wikipedia data from a JSON file), a minimal index.html entry point, a small JavaScript file and a huge CSS3 file.

I hope Part 1 explained what the calculations server-side are, and I'd like to touch lightly the jQuery and HTML parts because not very interesting, moving fast to the CSS3 code.

The HTML

A series of <div> objects define the structure with containers and IDs picked up later by JavaScript. Noteworthy are the inclusion of the CSS file in header and jQuery's CDN plus our code.js before the closing tag.

If you wonder how the i popups are made, they are entirely written in CSS (JS-less) thanks to :hover and ::after by populating the content property with the div's data-text with this:

.info:hover::after{
    content: attr(data-text);
    /* ... */
}

jQuery

There is no day that goes by without reading about ditching jQuery for modern frameworks like React (which I love) or Vue.js or Angular.

Still it sounds nuts to me.

The web is still using server-side code to generate HTML files to serve to the world: not everything is an app. You could make an argument about modern vanilla JS ES6 and jQuery, but not about replacing a simple page with a huge framework.

Take this simple timekeeping app I am presenting:

  • Calculations happen server-side,
  • 95% of animations are in CSS (one of the reasons behind this useless endeavour),
  • there is one single ajax call on loading
  • all JS needs to do is inject the data fetched or append divs when needed.

The 5% of animations left to JS are in the first digital clock showing the client's time and the world population counter. Another small task left to jQuery is creating popups with funny jokes. Not a vital feat.

If I were to generate the HTML file in PHP - creating the DOM elements and filling the data - I wouldn't have needed any JavaScript at all.

All modern JS framework don't handle well animations and even less extensive CSS (and its animations) without third-party libraries so even for the little it animates here, they would be not well suited.

There are no images (svg or otherwise) even for the carbon and mayan calendars backgrounds, they are CSS3 patterns found online. All other glossy, glassy, metally, rubbery layers are made by the author.

The elements

Digital clock

The first clock is showing the client's time, controlled by JS.

The fun part was devising a new structure for the strokes: every digit is made by 2 <div> tags and ::after and ::before of the first. I never saw this design online, the standard approach is creating a div for every stroke or use a digital clock like font.

Here's the ASCII art of it:

  - - 
/|\ /|\     BLACK: DIV WITH THICK BORDER AND TRANSPARENT BACKGROUND
  - - 
\|/ \|/     RED / GREEN: 45DEG ROTATED SQUARE (::AFTER / ::BEFORE)
  - - 

I hope you noted it is slightly shaking (with a CSS animation) as if it was in a moving car: I didn't need to put it, but I couldn't help it either!

Equinox / Solstice events

Not much to see here, the icon is a character and the text is enclosed in old-style metal boxes with shadows, :hover and funny messages on click.

These messages aren't really funny and could feel aggressive at times, but please notice that I have tried to keep sourcastic instead of full-on sarcaustic.

World population

A setInterval() in JS is updating the numbers from data fed by PHP, nothing special. The design is very old-school, with a gradient to give the feeling of roundness in the background and shadows and reflections attached to ::after elements.

If you wonder how to cover an element with its ::after element for design purposes (used extensively in this app), just set the former to...

position: relative; /* absolute, fixed, just not static */

and the latter...

.element::after{
    content: ''; /* somehow needed */
    position: absolute; /* relative to the closest non static parent */
    display: block;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    border-radius: inherit; /* nice to have the same shape of the parent */
    /* background: whatever; */
    /* box-shadow: whatever; */
}

Earth and Mars analog clocks

The funniest part of all this entire app. In itself this is not the best way to show time, quite the opposite, but the idea of having dials animated by css was just too appealing.

The dials are filled with JS based on:

  • data-qty gives us the amount of digits around the dials (60 for seconds and minutes, 12 for the hours)
  • data-start rotates the dial container to reflect a particular moment in time (I override this with data from PHP)
  • data-rotation this sets the speed of the animation in milliseconds.

jQuery sets the duration of the animation with...

rotatingChild.css({
    animationDuration: $(this).data('rotation') + 'ms',
});

and lets CSS take care of the rest. You could use this to rotate anything at any speed, like the Mars dial for the seconds that goes around every 61541.66664 milliseconds!

I let you discover how I made the hole in the glass effect.

Speed

Here we compare the speed of fast objects, the values are fed by jQuery and fetched from PHP.

This crazy shape is the result of experiments and a lot of fun moving around elements and their CSS properties. I hope you noted that the big white circle (::after) is rotating at the same speed of the containing object but in opposite direction, keeping its long shadow pointing down as reality would command.

I spent a lot of time just playing with this and I'm quite sorry I had to settle for one of the dozen amazing shapes I found.

Moon phases, remaining calendars and clickable objects

The .metal class is used for most clickable object, it is entirely controlled in CSS in all its states.

The moon phase graph is using elliptic radial-gradients based on the class injected by jQuery and coming from PHP data.

The remaining calendars use either a screen-terminal-retro-sci-fi design or flip digits counter on a CSS pattern (such as the Mayan calendar).

Final pause

I hope this could push people learning more about CSS3 and its wonderful possibilities or maybe someone could look at the math shown in Part 1 and re-use it somewhere, but in reality I do not care: I'm sorry this was for me and my love of timekeeping, and I have enjoyed every challenge I faced going through this project.

I have experimented a lot with linear / radial gradients and I feel much more comfortable creating my owns, I have played around with box and text shadows, enjoyed rotating and animating stuff: it was a badly needed re-sharpening of my CSS3 skills and most of all pure fun.

To make this endeavour a bit less selfish I could advise you to take on such a task yourself, just find any excuse for a side-project where you could represent data, any data, with challenging designs. Or don't.

I mean, sorry again, but if you don't want to learn any of this I won't force you and if you are here only for the copy/paste, then please, be my guest:

Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License.

Remember that the repo is on github.

Take your time, now.