AI CSS Animations

Seven Segment Digital Clock

An LED clock drawn from real seven-segment digits, seconds ticking and the colons blinking. Each segment reads a ten-cell color strip, so any digit is just --d: 0 to 9 on the element.

Also known as: digital clock css, 7 segment display css, led clock text.

HTML

<div class="txt-seven-segment-clock" aria-label="Digital clock">
  <span class="txt-seven-segment-clock-digit" style="--d: 0"><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span><span class="txt-seven-segment-clock-digit" style="--d: 9"><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span>
  <b class="txt-seven-segment-clock-colon"></b>
  <span class="txt-seven-segment-clock-digit" style="--d: 4"><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span><span class="txt-seven-segment-clock-digit" style="--d: 1"><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span>
  <b class="txt-seven-segment-clock-colon"></b>
  <span class="txt-seven-segment-clock-digit txt-seven-segment-clock-run" style="--n: 6; --p: 10s"><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span><span class="txt-seven-segment-clock-digit txt-seven-segment-clock-run" style="--n: 10; --p: 1s"><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span>
</div>

CSS

@property --txt-seven-segment-clock-n {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}
.txt-seven-segment-clock {
  --c: var(--txt-color, #3b82f6);
  font-size: calc(var(--txt-size, 32px) * 1.3);
  font-family: system-ui, sans-serif;
  font-weight: 700;
  line-height: 1.2;
  display: inline-flex;
  align-items: center;
  gap: 0.13em;
  padding: 0.32em 0.48em;
  border-radius: 0.22em;
  background: color-mix(in srgb, var(--c) 8%, #0b0d10);
  --on: var(--c);
  --off: color-mix(in srgb, var(--c) 13%, transparent);}
.txt-seven-segment-clock-digit {
  position: relative;
  width: 0.72em;
  height: 1.3em;
  transform: skewX(-7deg);
  filter: drop-shadow(0 0 0.08em color-mix(in srgb, var(--c) 60%, transparent));
}
/* segments a, b, c, d, e, f, g in source order */
.txt-seven-segment-clock-digit i {
  position: absolute;
  /* slide the ten-cell strip so cell --d shows */
  background-size: 1000% 100%;
  background-position: calc(var(--d) * 100% / 9) 0;
}
.txt-seven-segment-clock-digit i:is(:nth-child(1), :nth-child(4), :nth-child(7)) {
  left: 0.07em;
  right: 0.07em;
  height: 0.12em;
  clip-path: polygon(0.06em 0, calc(100% - 0.06em) 0, 100% 50%, calc(100% - 0.06em) 100%, 0.06em 100%, 0 50%);
}
.txt-seven-segment-clock-digit i:is(:nth-child(2), :nth-child(3), :nth-child(5), :nth-child(6)) {
  width: 0.12em;
  height: calc(50% - 0.12em);
  clip-path: polygon(50% 0, 100% 0.06em, 100% calc(100% - 0.06em), 50% 100%, 0 calc(100% - 0.06em), 0 0.06em);
}
.txt-seven-segment-clock-digit i:nth-child(1) { top: 0; background-image: linear-gradient(90deg, var(--on) 0% 10%, var(--off) 10% 20%, var(--on) 20% 40%, var(--off) 40% 50%, var(--on) 50% 100%); }
.txt-seven-segment-clock-digit i:nth-child(2) { right: 0; top: 0.06em; background-image: linear-gradient(90deg, var(--on) 0% 50%, var(--off) 50% 70%, var(--on) 70% 100%); }
.txt-seven-segment-clock-digit i:nth-child(3) { right: 0; bottom: 0.06em; background-image: linear-gradient(90deg, var(--on) 0% 20%, var(--off) 20% 30%, var(--on) 30% 100%); }
.txt-seven-segment-clock-digit i:nth-child(4) { bottom: 0; background-image: linear-gradient(90deg, var(--on) 0% 10%, var(--off) 10% 20%, var(--on) 20% 40%, var(--off) 40% 50%, var(--on) 50% 70%, var(--off) 70% 80%, var(--on) 80% 100%); }
.txt-seven-segment-clock-digit i:nth-child(5) { left: 0; bottom: 0.06em; background-image: linear-gradient(90deg, var(--on) 0% 10%, var(--off) 10% 20%, var(--on) 20% 30%, var(--off) 30% 60%, var(--on) 60% 70%, var(--off) 70% 80%, var(--on) 80% 90%, var(--off) 90% 100%); }
.txt-seven-segment-clock-digit i:nth-child(6) { left: 0; top: 0.06em; background-image: linear-gradient(90deg, var(--on) 0% 10%, var(--off) 10% 40%, var(--on) 40% 70%, var(--off) 70% 80%, var(--on) 80% 100%); }
.txt-seven-segment-clock-digit i:nth-child(7) { top: calc(50% - 0.06em); background-image: linear-gradient(90deg, var(--off) 0% 20%, var(--on) 20% 70%, var(--off) 70% 80%, var(--on) 80% 100%); }
/* the running seconds: an integer steps 0 to 9 (or 0 to 5) and feeds --d */
.txt-seven-segment-clock-run {
  --d: var(--txt-seven-segment-clock-n);
  animation: txt-seven-segment-clock-count calc(var(--p) * var(--n)) steps(var(--n)) -7s infinite;
}
.txt-seven-segment-clock-colon {
  width: 0.13em;
  height: 0.62em;
  background:
    radial-gradient(circle closest-side, var(--c) 92%, transparent) top / 0.13em 0.13em no-repeat,
    radial-gradient(circle closest-side, var(--c) 92%, transparent) bottom / 0.13em 0.13em no-repeat;
  filter: drop-shadow(0 0 0.08em color-mix(in srgb, var(--c) 60%, transparent));
  animation: txt-seven-segment-clock-blink 1s steps(1) infinite;
}
@keyframes txt-seven-segment-clock-count {
  to { --txt-seven-segment-clock-n: var(--n); }
}
@keyframes txt-seven-segment-clock-blink {
  50% { opacity: 0.2; }
}

@media (prefers-reduced-motion: reduce) {
  .txt-seven-segment-clock, .txt-seven-segment-clock *, .txt-seven-segment-clock::before, .txt-seven-segment-clock::after, .txt-seven-segment-clock *::before, .txt-seven-segment-clock *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --txt-color on the element or a parent. Currently previewing #3b82f6.
  • Font size: set --txt-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 40px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar text animations