Skip to content

Live Analog Clock

Live analog clock with CSS-rotated hands, conic-gradient ticks, a digital readout and optional time zone support, in pure CSS and vanilla JS.

Live preview

Open in new tab

Code

A live analog clock with a warm, soft-shadowed face, CSS-drawn ticks and hands, and a digital readout underneath. It is built with pure CSS and a small vanilla JavaScript file and fits dashboards, landing pages, world-clock panels and office displays.

How it works

The root figure.ac-clock holds the round .ac-face and a figcaption.ac-caption with the label, digital time and date. The 60 minute ticks and 12 hour ticks are not separate elements: .ac-ring stacks two repeating-conic-gradient backgrounds (one every 6 degrees, one every 30 degrees) and a radial mask cuts them down to a thin ring. The numerals 12, 3, 6 and 9 are absolutely positioned .ac-num spans.

Each hand is a .ac-hand anchored at the center with transform-origin at its base and rotated by a custom property: .ac-hand--hour uses --ac-h, .ac-hand--min uses --ac-m and .ac-hand--sec uses --ac-s. The second hand extends past the center as a counterweight, so its origin sits at 75% of its height. Default values in the CSS show 10:09:30, so the clock looks right before the script runs.

On DOMContentLoaded the script initializes every .ac-clock. Four times per second it reads the current time with Intl.DateTimeFormat, and when the second changes it writes the three angles as inline custom properties, updates .ac-digital and .ac-date, and refreshes the label of the face. The second hand angle keeps growing after 59 instead of jumping back to 0, so the short springy transition (enabled through the is-ready class after the first update) never spins it backwards.

Customization

  • data-ac-timezone on .ac-clock: an IANA zone such as Europe/London or Asia/Tokyo shows that zone instead of the visitor's local time; an invalid value falls back to local time.
  • data-ac-label: the text shown in .ac-label above the digital time, e.g. "New York office".
  • --ac-size: the diameter of the face; numerals, hand widths and the center cap scale with it.
  • --ac-accent: the color of the second hand, the center cap ring and the label.
  • --ac-bg, --ac-face and --ac-ink: the card background, the dial color and the color of hands, ticks and numerals.
  • --ac-tick: the color of the thin minute ticks in .ac-ring.
  • Remove .ac-brand for a cleaner dial, or the whole .ac-caption for a clock without digital readout.

Accessibility

The dial has role="img" and an aria-label such as "Analog clock showing 14:05", updated once per minute, while the decorative ticks, numerals and hands are aria-hidden. The digital time element gives a readable alternative and its datetime attribute stays in sync. The clock has no interactive controls, so it adds nothing to the tab order. With prefers-reduced-motion: reduce the second hand moves without the spring transition. Ink colors on the cream face exceed WCAG AA contrast.

Usage notes

Several clocks can share a page, each with its own data-ac-timezone, which makes a simple world-clock row easy. The script uses formatToParts, supported in all current browsers.

Requirements

No dependencies. Pure HTML, CSS and JavaScript.

Live Analog Clock – Pure CSS clocks component screenshot
Live Analog Clock · Pure CSS Clocks