Skip to content

CSS analog clock face — minimalist Orbit example

The minimalist analog clock is the starting point for every other watch face. Get this right and the rest — chronographs, smartwatches, sub-dials — are just additions on top. The essentials are: a numbered ring of hours, two layers of tick marks (twelve big ones for the hours, sixty small ones for the minutes), and two hands that share a center.

This example builds exactly that. The “watch frame” is rendered with two flat-grey rings (the bezel and the dial), and the hands are two vector elements rotated to specific angles. To make it tell live time, swap the angles for Date.now()-derived values.

How it works

  • Two stacked dial discs at orbit-11 create depth: the outer one is the bezel, the inner back is the dial face. Setting them to slightly different greys gives a subtle “raised” feel without any shadow tricks.
  • Three layers of tick marks make the dial feel professional: twelve big ticks at the hours (the first orbit-10), sixty minute ticks (shrink-50 for shorter), and another sixty offset ticks (from-3 rotates them slightly) to add density. This is why a watch face from the 1960s feels different from a paper print of one.
  • Hour labels are satellites on orbit-8 — slightly inside the tick row. The 12 is hard-coded first to anchor the position; the rest are generated by Vue’s v-for. In a vanilla project, just write all twelve.
  • Hands at orbit-0 with grow-Nx extend out to the right radius. angle-45 for the minute hand and angle-300 for the hour hand snapshots a specific time. To make the clock live, replace those classes with dynamic angles computed from new Date().

Customization

Make it tell live time by setting the hand angles every second:

function tick() {
const d = new Date();
const minuteAngle = d.getMinutes() * 6 - 90; // 6° per minute
const hourAngle = (d.getHours() % 12) * 30 + d.getMinutes() / 2 - 90;
document.querySelector('.minute').style.setProperty('--o-angle-composite', minuteAngle + 'deg');
document.querySelector('.hour').style.setProperty('--o-angle-composite', hourAngle + 'deg');
}
setInterval(tick, 1000);

Add a second hand by adding a thinner red vector at orbit-0 and updating it on the same interval.

Switch to a dark dial by changing .back { background-color: #111 } and .clock-frame { color: #f0f0f0 }.

Use this in your project

Install Orbit CSS and the markup above is your entire clock.