Skip to content

Repository files navigation

Digital Clock Card

A digital clock for Home Assistant whose digits are solved to fill the whole card — all four edges, at any card size or shape.

The card with a background, in 12-hour mode, and with no background at all

Open your Home Assistant instance and open this repository inside the Home Assistant Community Store.

Most "big text" cards pick a font size and hope. This one measures. Text has a fixed aspect ratio, so scaling alone can never make 09:14 touch all four edges of an arbitrary rectangle. Instead the card drives the wdth axis of a variable font until the time's proportions match the card's, and only then falls back to distortion.


Installing

HACS

  1. HACS → Frontend → ⋮ → Custom repositories
  2. Add https://github.com/fwhitten/digital-clock-card with the category Lovelace
  3. Install Digital Clock Card, then reload your browser

Manually

  1. Download digital-clock-card.js from the latest release
  2. Copy it to config/www/
  3. Add the resource under Settings → Dashboards → ⋮ → Resources: /local/digital-clock-card.js, type JavaScript Module

Then add the card from the picker. It needs no entity, and everything is configurable from the visual editor.


Options

Every option is available in the visual editor. The YAML names are listed for anyone who prefers to type.

Option Default Description
hour_format "24" "24" for 09:14, "12" for 9:14 AM.
leading_zero true 12-hour only. Off shows 9:14. The clock resizes as the hour gains a digit.
show_meridiem true 12-hour only. Adds a full-height stacked AM/PM column.
font_weight 400 100–900, continuous. See weight and card shape.
background true Off makes the card fully transparent, with the digits edge to edge and no padding at all.
padding 8 Percentage of the card's shorter side left clear. Only applies with a background.
stretch_to_fill true What to do when the card is a more extreme shape than the width axis can reach. See filling.
aspect_ratio 3 Only used in the masonry view, where cards size to their content instead of to a grid.
time_animation "fade" none, fade or swipe. Only the digits that changed animate.
swipe_direction "up" up or down. Swipe only.
colon_blink "none" none, flash or fade. Blinks once a second, locked to the real clock.
color theme A Home Assistant colour name (primary, red, orange, …). Follows the theme into dark mode.
color_light / color_dark Exact CSS colours that override color, chosen by the active theme's mode.
background_color theme As color, for the card background.
background_color_light / background_color_dark As above, exact values.
tap_action / hold_action / double_tap_action none Standard Home Assistant actions.

Examples

The smallest possible card:

type: custom:digital-clock-card

A frameless clock that fills its grid cell completely:

type: custom:digital-clock-card
background: false
font_weight: 250
colon_blink: fade
time_animation: swipe

A bold 12-hour clock in the theme's accent colour:

type: custom:digital-clock-card
hour_format: "12"
leading_zero: false
font_weight: 800
color: accent
tap_action:
  action: navigate
  navigation_path: /lovelace/clock

How the fill works

The card is given a rectangle and has to make the ink of 09:14 touch every edge of it.

  1. Solve the width axis. Archivo's wdth axis runs from 62 to 125, which changes a digit's advance by about two thirds. The card bisects that axis for the width at which the time's aspect ratio equals the card's, so the digits reach both pairs of edges while keeping their proper shapes.
  2. Size to the ink, not the line. A font's line box includes ascender and descender space that digits never occupy; sizing to it leaves a stubborn gap above and below. The card works from the ink box of the digits, measured from the font itself at build time, so the tops of the digits sit exactly on the top edge.
  3. Distort only as a last resort. If the card is a more extreme shape than the width axis can reach, stretch_to_fill decides what happens: stretch the digits to cover the remainder (the default, so the card is always full), or leave them undistorted and centred, with a gap.

All of this is arithmetic over a metric table extracted from the font when the card is built, so resizing costs no layout measurement and the first frame is already correct. The only thing measured in the browser is where it places the baseline, which is calibrated once.

Because the digits are tabular — every digit has exactly the same advance at every point on both axes — the layout is solved once and never moves as the time changes. A 1 does not make the clock jump.

Weight and card shape

Heavier digits cannot be squeezed as narrow, so the weight you choose sets the range of card shapes that can be filled without any distortion:

Font weight Narrowest card Widest card
100 2.44 : 1 4.03 : 1
200 2.46 : 1 4.10 : 1
300 2.49 : 1 4.19 : 1
400 2.52 : 1 4.30 : 1
500 2.55 : 1 4.41 : 1
600 2.59 : 1 4.54 : 1
700 2.62 : 1 4.65 : 1
800 2.67 : 1 4.82 : 1
900 2.75 : 1 5.05 : 1

(Ratios are for a four-digit 24-hour clock; a stacked AM/PM column widens them slightly.)

A wide, short card is what Archivo's width axis is built for. Because that axis only spans 62–125, the band is narrow and the weight barely widens it: nothing narrower than about 2.4:1 can be filled without stretching, at any weight. Square and portrait cards get stretched noticeably, so give the card a wide, short slot where you can. The editor shows the reachable range beneath the weight slider as you drag it.


Sizing

The card implements getGridOptions(), so in the sections view it can be dragged to any size and reflows instantly; it defaults to full width and two rows, and will go as small as three columns by one row.

In the older masonry view, cards size to their content and there is no height to fill, so the card falls back to the configured aspect_ratio.

Behaviour worth knowing

  • Theme. Colours come from the active Home Assistant theme, so light and dark follow whatever the user has set — including "auto", which tracks the system. Explicit colours can be given separately for each mode.
  • Efficiency. The clock schedules a single timer aligned to the next minute rather than polling, and stops entirely while its tab is hidden, catching up when it comes back. The blinking colon runs as a compositor animation, phase- locked to the wall clock, so no per-second JavaScript is involved.
  • Reduced motion. Digit transitions and the blinking colon are disabled automatically when the browser reports prefers-reduced-motion.
  • Accessibility. The card exposes the time as a timer role with a readable label, and becomes a focusable button when an action is configured.
  • Offline. The font is subset to the fourteen glyphs a clock needs and embedded in the bundle (under 9KB), so nothing is fetched from a third party and the card works on installs with no internet access.
  • Tabular figures. Archivo's digits are proportional by default, which would make the clock re-solve and jump every minute. The build remaps the digit codepoints onto the font's tabular figures, so every digit has an identical advance at every point on both axes and the layout never moves.

Development

npm install
npm run build     # -> dist/digital-clock-card.js
npm run watch

There is a harness at dev/index.html that renders the card at a spread of sizes and configurations against stand-ins for the frontend's elements, and audits how exactly the digits meet each edge:

npx http-server -p 8177 . 

Then open http://localhost:8177/dev/ and call audit() from the console.

docs/preview.svg in the README is generated too, with the glyphs converted to paths so it needs no embedded font:

.venv/bin/python tools/build-preview.py

It re-implements the layout solver against exact font instances rather than the interpolated table, so the two act as a check on each other - they currently agree on font size to 0.003% and on the width axis to 0.10%.

Rebuilding the font

src/font-data.ts is generated. It holds the subset woff2 and the metric grid the solver interpolates. To regenerate it — after changing which glyphs are included, or the sampling grid:

python3 -m venv .venv && .venv/bin/pip install -r tools/requirements.txt
.venv/bin/python tools/build-font.py

Licence

The card is MIT licensed — see LICENSE.

It embeds a subset of Archivo by Omnibus-Type, which is licensed separately under the SIL Open Font License 1.1 — see OFL.txt and NOTICE.

About

A Home Assistant digital clock card whose digits are solved to fill the whole card, using a variable font.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages