Advertisement

Bouncy Digital Block Clock

| by Vladimir | 2 min read | code by Jon Kantner
A11y Ready Intermediate

Tech & Dependencies

HTML CSS JavaScript

Features

  • Bouncing Animation
  • Rolling Digits
  • Dark Mode
  • Responsive Scaling

Browser Support

Chrome 60+ Edge 79+ Firefox 60+ Safari 12+

Core

This Bouncy Digital Block Clock transforms a standard time display into a playful, tactile UI element. It utilizes a split-digit technique where numbers “roll” into place while their container physically bounces, adding weight and character to every second that passes. The component is fully responsive, supports system dark mode automatically, and ensures accessibility via dynamic ARIA labels.

Core Technique

The animation relies on two synchronized CSS @keyframes triggered by JavaScript. The HTML structure for each number block contains two digits: the previous time (data-time="a") and the new time (data-time="b").

When the JavaScript detects a time change, it adds the .clock__block--bounce class. This triggers:

  1. The Bounce: The outer container (.clock__block) scales and translates vertically using animation: bounce.
  2. The Roll: The inner container (.clock__digit-group) slides upward from -50% to 0% using animation: roll. This creates the illusion of the old number rolling away and the new one rolling in.

Customization

The design relies heavily on HSL color variables, making theming extremely easy. You can change the base hue in the :root to alter the entire color scheme (background, blocks, and shadows) simultaneously.

:root {
  /* Change the hue (0-360) for a different color theme */
  --hue: 223; /* Blue */
  
  /* Adjust animation speed */
  --trans-dur: 0.3s;
}

/* Adjust the bounce intensity */
@keyframes bounce {
  50% {
    /* Increase percentage for higher bounce */
    transform: translateY(15%); 
  }
}

To modify the rhythm of the animation, you can adjust the stagger delays in the CSS.

/* Delay for minutes */
.clock__block--delay1 {
  animation-delay: 0.1s;
}
/* Delay for seconds */
.clock__block--delay2 {
  animation-delay: 0.2s;
}

Tips

1. Accessibility is handled correctly: The developer uses a clever pattern here. The individual blocks have aria-hidden="true", meaning screen readers ignore the complex DOM structure used for animation. Instead, the parent container gets a dynamic aria-label updated by JS.

displayTime() {
  // ... gets digits ...
  // This ensures screen readers read "10:45:00 PM" naturally
  this.el.ariaLabel = `${timeDigits.join(":")} ${ap}`; 
  // ...
}

2. Fluid Typography: The font size is calculated based on the viewport width using calc(). This is a robust way to ensure the clock scales linearly between mobile (320px) and desktop (1280px) without needing dozens of media queries.

/* Formula: Base + (Max - Min) * (CurrentVW - MinVW) / (MaxVW - MinVW) */
font-size: calc(16px + (20 - 16) * (100vw - 320px) / (1280 - 320));
Advertisement