Marketing

Stat Row

Four figures dropping in with a small overshoot.

58
motion presets
17
components
12
export formats
0
accounts
8
Elements
5
Groups
0
Hover states
1420ms
Duration

Why it is timed this way

The reasoning

The overshoot gives each number a little weight as it lands, which is most of why a statistic reads as confident rather than merely present. CSS cannot count a number up, so the motion carries the emphasis instead.

8 elements move, the first at 0ms and the last starting at 420ms — the whole scene settles by 1420ms. Every bar below is one element's animation window.

Stat 1
Label 1
Stat 2
Label 2
Stat 3
Label 3
Stat 4
Label 4
0ms710ms1420ms

The code

Everything the scene needs, in whichever format you ship. Entrances compile to@keyframesand hover states totransition, with a reduced-motion guard on both.

320 lines
.stats {
  transform: translate3d(0px, 0px, 0);
  width: 960px;
  height: 480px;
  transform-origin: 374px 164px;
}

.stat-col-1 {
  transform: translate3d(0px, 0px, 0);
  height: 86px;
  transform-origin: 95px 43px;
}

.stat-col-2 {
  transform: translate3d(0px, 0px, 0);
  height: 86px;
  transform-origin: 95px 43px;
}

.stat-col-3 {
  transform: translate3d(0px, 0px, 0);
  height: 86px;
  transform-origin: 95px 43px;
}

.stat-col-4 {
  transform: translate3d(0px, 0px, 0);
  height: 86px;
  transform-origin: 95px 43px;
}

.stat-1 {
  transform: translate3d(0px, 0px, 0);
  height: 60px;
  background: #00000000;
  color: #eceef4;
  font-size: 52px;
  font-weight: 800;
  animation: stat-1-anim 1420ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes stat-1-anim {
  0% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
    animation-timing-function: ease-out;
  }
  45.07% {
    transform: translate3d(0px, 11.148px, 0) scale(1.014, 1.014);
    opacity: 1;
  }
  56.34% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.label-1 {
  transform: translate3d(0px, 0px, 0);
  height: 20px;
  background: #00000000;
  color: #98a1b5;
  font-size: 14px;
  font-weight: 500;
  animation: label-1-anim 1420ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes label-1-anim {
  0% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
  }
  4.23% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
    animation-timing-function: ease-out;
  }
  49.3% {
    transform: translate3d(0px, 11.148px, 0) scale(1.014, 1.014);
    opacity: 1;
  }
  60.56% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.stat-2 {
  transform: translate3d(0px, 0px, 0);
  height: 60px;
  background: #00000000;
  color: #eceef4;
  font-size: 52px;
  font-weight: 800;
  animation: stat-2-anim 1420ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes stat-2-anim {
  0% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
  }
  8.45% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
    animation-timing-function: ease-out;
  }
  53.52% {
    transform: translate3d(0px, 11.148px, 0) scale(1.014, 1.014);
    opacity: 1;
  }
  64.79% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.label-2 {
  transform: translate3d(0px, 0px, 0);
  height: 20px;
  background: #00000000;
  color: #98a1b5;
  font-size: 14px;
  font-weight: 500;
  animation: label-2-anim 1420ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes label-2-anim {
  0% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
  }
  12.68% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
    animation-timing-function: ease-out;
  }
  57.75% {
    transform: translate3d(0px, 11.148px, 0) scale(1.014, 1.014);
    opacity: 1;
  }
  69.01% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.stat-3 {
  transform: translate3d(0px, 0px, 0);
  height: 60px;
  background: #00000000;
  color: #eceef4;
  font-size: 52px;
  font-weight: 800;
  animation: stat-3-anim 1420ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes stat-3-anim {
  0% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
  }
  16.9% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
    animation-timing-function: ease-out;
  }
  61.97% {
    transform: translate3d(0px, 11.148px, 0) scale(1.014, 1.014);
    opacity: 1;
  }
  73.24% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.label-3 {
  transform: translate3d(0px, 0px, 0);
  height: 20px;
  background: #00000000;
  color: #98a1b5;
  font-size: 14px;
  font-weight: 500;
  animation: label-3-anim 1420ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes label-3-anim {
  0% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
  }
  21.13% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
    animation-timing-function: ease-out;
  }
  66.2% {
    transform: translate3d(0px, 11.148px, 0) scale(1.014, 1.014);
    opacity: 1;
  }
  77.46% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.stat-4 {
  transform: translate3d(0px, 0px, 0);
  height: 60px;
  background: #00000000;
  color: #22d3ee;
  font-size: 52px;
  font-weight: 800;
  animation: stat-4-anim 1420ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes stat-4-anim {
  0% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
  }
  25.35% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
    animation-timing-function: ease-out;
  }
  70.42% {
    transform: translate3d(0px, 11.148px, 0) scale(1.014, 1.014);
    opacity: 1;
  }
  81.69% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

.label-4 {
  transform: translate3d(0px, 0px, 0);
  height: 20px;
  background: #00000000;
  color: #98a1b5;
  font-size: 14px;
  font-weight: 500;
  animation: label-4-anim 1420ms linear 0ms infinite both;
  will-change: transform, opacity;
}

@keyframes label-4-anim {
  0% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
  }
  29.58% {
    transform: translate3d(0px, -240px, 0) scale(0.7, 0.7);
    opacity: 0.4;
    animation-timing-function: ease-out;
  }
  74.65% {
    transform: translate3d(0px, 11.148px, 0) scale(1.014, 1.014);
    opacity: 1;
  }
  85.92% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
  100% {
    transform: translate3d(0px, 0px, 0);
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .stat-1,
  .label-1,
  .stat-2,
  .label-2,
  .stat-3,
  .label-3,
  .stat-4,
  .label-4 {
    animation: none;
    transition: none;
  }
}

More scenes

Starter
$0
Pro
$12
Team
$40

Three-Plan Pricing

Three plans that pop in, with the featured column raised and hover lifts on every card.

Canvas
Timeline
Easing
States
Export
Import

Feature Tile Grid

Six tiles arriving as a wave across the grid, each lifting on hover.

Frontend engineer
Design systems
It replaced three tools and a
folder of half-finished CSS.

Testimonial Card

A quote card that rises into place, avatar first.