AI CSS Animations

T-Minus Launch Countdown

A mission clock counts T-00:00:10 down to zero as ten segments go dark one by one, then flips to T+ with all segments lit and Liftoff in your color. One inherited integer drives the clock and the bar.

Also known as: css countdown animation, countdown css animation, rocket launch countdown, 10 to 0 countdown.

HTML

<div class="txt-t-minus-launch-countdown" aria-label="Launch countdown from T minus 10 seconds">
  <span class="txt-t-minus-launch-countdown-label" aria-hidden="true"><span>Launch window open</span><span>Liftoff</span></span>
  <span class="txt-t-minus-launch-countdown-clock" aria-hidden="true"><span class="txt-t-minus-launch-countdown-sign"><span>T-</span><span>T+</span></span><span class="txt-t-minus-launch-countdown-num"></span></span>
  <span class="txt-t-minus-launch-countdown-segs" aria-hidden="true"><i style="--i: 0"></i><i style="--i: 1"></i><i style="--i: 2"></i><i style="--i: 3"></i><i style="--i: 4"></i><i style="--i: 5"></i><i style="--i: 6"></i><i style="--i: 7"></i><i style="--i: 8"></i><i style="--i: 9"></i></span>
</div>

CSS

@property --txt-t-minus-launch-countdown-n {
  syntax: "<integer>";
  initial-value: 0;
  inherits: true;
}
@property --txt-t-minus-launch-countdown-up {
  syntax: "<integer>";
  initial-value: 1;
  inherits: true;
}
.txt-t-minus-launch-countdown {
  --c: var(--txt-color, #3b82f6);
  font-size: calc(var(--txt-size, 32px) * 0.9);
  font-family: system-ui, sans-serif;
  font-weight: 700;
  line-height: 1.2;
  display: inline-grid;
  justify-items: start;
  gap: 0.3em;
  --t: 13s;
  animation:
    txt-t-minus-launch-countdown-n var(--t) step-end infinite,
    txt-t-minus-launch-countdown-up var(--t) step-end infinite;}
.txt-t-minus-launch-countdown-label {
  display: grid;
  font-size: 0.42em;
  font-weight: 650;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.txt-t-minus-launch-countdown-label span {
  grid-area: 1 / 1;
}
.txt-t-minus-launch-countdown-label span:last-child {
  color: var(--c);
  opacity: var(--txt-t-minus-launch-countdown-up);
}
.txt-t-minus-launch-countdown-label span:first-child {
  opacity: calc(0.55 - var(--txt-t-minus-launch-countdown-up) * 0.55);
}
.txt-t-minus-launch-countdown-clock {
  display: flex;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1.45em;
  font-weight: 600;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.txt-t-minus-launch-countdown-sign {
  display: grid;
}
.txt-t-minus-launch-countdown-sign span {
  grid-area: 1 / 1;
  opacity: calc(1 - var(--txt-t-minus-launch-countdown-up));
}
.txt-t-minus-launch-countdown-sign span:last-child {
  color: var(--c);
  opacity: var(--txt-t-minus-launch-countdown-up);
}
.txt-t-minus-launch-countdown-num {
  counter-reset: txt-t-minus-launch-countdown-s var(--txt-t-minus-launch-countdown-n);
}
.txt-t-minus-launch-countdown-num::before {
  content: "00:00:" counter(txt-t-minus-launch-countdown-s, decimal-leading-zero);
}
.txt-t-minus-launch-countdown-segs {
  display: flex;
  gap: 0.12em;
}
.txt-t-minus-launch-countdown-segs i {
  width: 0.48em;
  height: 0.2em;
  border-radius: 0.1em;
  background: var(--c);
  /* lit while the count is above this segment, or after liftoff */
  opacity: clamp(0.14, calc(var(--txt-t-minus-launch-countdown-n) - var(--i) + var(--txt-t-minus-launch-countdown-up) * 10), 1);
  box-shadow: 0 0 calc(var(--txt-t-minus-launch-countdown-up) * 0.4em) var(--c);
  transition: opacity 0.35s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.35s;
}
@keyframes txt-t-minus-launch-countdown-n {
  0% { --txt-t-minus-launch-countdown-n: 10; }
  7.69% { --txt-t-minus-launch-countdown-n: 9; }
  15.38% { --txt-t-minus-launch-countdown-n: 8; }
  23.08% { --txt-t-minus-launch-countdown-n: 7; }
  30.77% { --txt-t-minus-launch-countdown-n: 6; }
  38.46% { --txt-t-minus-launch-countdown-n: 5; }
  46.15% { --txt-t-minus-launch-countdown-n: 4; }
  53.85% { --txt-t-minus-launch-countdown-n: 3; }
  61.54% { --txt-t-minus-launch-countdown-n: 2; }
  69.23% { --txt-t-minus-launch-countdown-n: 1; }
  76.92% { --txt-t-minus-launch-countdown-n: 0; }
  84.62% { --txt-t-minus-launch-countdown-n: 1; }
  92.31% { --txt-t-minus-launch-countdown-n: 2; }
}
@keyframes txt-t-minus-launch-countdown-up {
  0% { --txt-t-minus-launch-countdown-up: 0; }
  76.92% { --txt-t-minus-launch-countdown-up: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .txt-t-minus-launch-countdown, .txt-t-minus-launch-countdown *, .txt-t-minus-launch-countdown *::before, .txt-t-minus-launch-countdown *::after { animation: none !important; }
}

@media (prefers-reduced-motion: reduce) {
  .txt-t-minus-launch-countdown, .txt-t-minus-launch-countdown *, .txt-t-minus-launch-countdown::before, .txt-t-minus-launch-countdown::after, .txt-t-minus-launch-countdown *::before, .txt-t-minus-launch-countdown *::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