Skip to content

ExpressiveCSS

Browse documentation

Countdown

A number from 0 to 999 whose digits roll to each new value.

View as Markdown

On this page

A .countdown shows a whole number from 0 to 999. When the number changes, its digits roll up or down to the new value.

Set --md-comp-countdown-value to the number and write the same number as the element's text. Change both together. CSS draws the digits you see and hides them from screen readers, so assistive technology reads the text. Values below 0 show 0 and values above 999 show 999. Size and color come from the surrounding text. The component is CSS only, and your script sets the value.

60

<span id="countdown" class="countdown" style="--md-comp-countdown-value: 60">60</span>

<script>
  const countdown = document.getElementById('countdown');
  let value = 60;
  setInterval(() => {
    value = value === 0 ? 60 : value - 1;
    countdown.style.setProperty('--md-comp-countdown-value', value);
    countdown.textContent = value;
  }, 1000);
</script>

Clock

The box is as wide as the number. Set --md-comp-countdown-digits to 2 or 3 to pad with leading zeros, so a clock keeps its width as it ticks.

A role="timer" container stays quiet while the numbers change. A screen reader reads the time when the user reaches it, not once a second. Use aria-live="polite" instead when each new value needs to be announced, such as a count that changes only after the user does something.

00:00:00

<p id="clock-timer" role="timer" style="--md-comp-countdown-digits: 2">
  <span class="countdown" style="--md-comp-countdown-value: 9">09</span>:<span
        class="countdown" style="--md-comp-countdown-value: 41">41</span>:<span
        class="countdown" style="--md-comp-countdown-value: 5">05</span>
</p>

<script>
  const [h, m, s] = document.querySelectorAll('#clock-timer .countdown');
  const show = (el, n) => {
    el.style.setProperty('--md-comp-countdown-value', n);
    el.textContent = String(n).padStart(2, '0');
  };
  const tick = () => {
    const now = new Date();
    show(h, now.getHours());
    show(m, now.getMinutes());
    show(s, now.getSeconds());
  };
  tick();
  setInterval(tick, 1000);
</script>

Tokens

Set the value on each .countdown. Set the rest on the countdown or on an ancestor.

Token Default
--md-comp-countdown-value 0; the number shown, 0 to 999
--md-comp-countdown-digits 1; at least this many digits, padded with zeros
--md-comp-countdown-duration 400ms
--md-comp-countdown-easing cubic-bezier(0.2, 0, 0, 1)

With reduced motion, the digits change without rolling.

No matching pages

  • Source color

    The seed every generated ramp derives from. Pick one and browse the docs — the whole theme follows. Error does not: it is a fixed hue.

    Default source: Mist Iris.

    ExpressiveCSS presets: Lagoon, Harbor, Breeze, Cobalt, Iris.

    Bold

    Soft

    Mist

    Glow