AI CSS Animations

Material Linear Progress Bar

Google's indeterminate linear indicator: two segments chase across the track, each stretching and shrinking on the Material easing curves. Transform only, so it stays smooth.

Also known as: material indeterminate progress bar, android linear progress indicator, google loading bar.

HTML

<div class="ldr-material-linear-progress" role="progressbar" aria-label="Loading">
  <span class="ldr-material-linear-progress-primary"><span></span></span>
  <span class="ldr-material-linear-progress-secondary"><span></span></span>
</div>

CSS

.ldr-material-linear-progress {
  --s: var(--ldr-size, 48px);
  --c: var(--ldr-color, #3b82f6);
  position: relative;
  width: calc(var(--s) * 6);
  height: calc(var(--s) / 10);
  overflow: hidden;
  background: color-mix(in srgb, var(--ldr-color, #3b82f6) 22%, transparent);
}
.ldr-material-linear-progress > span {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}
.ldr-material-linear-progress > span > span {
  position: absolute;
  inset: 0;
  background: var(--c);
}
.ldr-material-linear-progress-primary {
  left: -145.166611%;
  animation: ldr-material-linear-progress-primary-move 2s linear infinite;
}
.ldr-material-linear-progress-primary > span {
  animation: ldr-material-linear-progress-primary-scale 2s linear infinite;
}
.ldr-material-linear-progress-secondary {
  left: -54.888891%;
  animation: ldr-material-linear-progress-secondary-move 2s linear infinite;
}
.ldr-material-linear-progress-secondary > span {
  animation: ldr-material-linear-progress-secondary-scale 2s linear infinite;
}
@keyframes ldr-material-linear-progress-primary-move {
  0%     { transform: translateX(0); }
  20%    { transform: translateX(0); animation-timing-function: cubic-bezier(0.5, 0, 0.701732, 0.495819); }
  59.15% { transform: translateX(83.67142%); animation-timing-function: cubic-bezier(0.302435, 0.381352, 0.55, 0.956352); }
  100%   { transform: translateX(200.611057%); }
}
@keyframes ldr-material-linear-progress-primary-scale {
  0%     { transform: scaleX(0.08); }
  36.65% { transform: scaleX(0.08); animation-timing-function: cubic-bezier(0.334731, 0.12482, 0.785844, 1); }
  69.15% { transform: scaleX(0.661479); animation-timing-function: cubic-bezier(0.06, 0.11, 0.6, 1); }
  100%   { transform: scaleX(0.08); }
}
@keyframes ldr-material-linear-progress-secondary-move {
  0%     { transform: translateX(0); animation-timing-function: cubic-bezier(0.15, 0, 0.515058, 0.409685); }
  25%    { transform: translateX(37.651913%); animation-timing-function: cubic-bezier(0.31033, 0.284058, 0.8, 0.733712); }
  48.35% { transform: translateX(84.386165%); animation-timing-function: cubic-bezier(0.4, 0.627035, 0.6, 0.902026); }
  100%   { transform: translateX(160.277782%); }
}
@keyframes ldr-material-linear-progress-secondary-scale {
  0%     { transform: scaleX(0.08); animation-timing-function: cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971); }
  19.15% { transform: scaleX(0.457104); animation-timing-function: cubic-bezier(0.152313, 0.196432, 0.648374, 1.004315); }
  44.15% { transform: scaleX(0.72796); animation-timing-function: cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179); }
  100%   { transform: scaleX(0.08); }
}

@media (prefers-reduced-motion: reduce) {
  .ldr-material-linear-progress, .ldr-material-linear-progress *, .ldr-material-linear-progress::before, .ldr-material-linear-progress::after, .ldr-material-linear-progress *::before, .ldr-material-linear-progress *::after {
    animation-duration: 3s;
  }
}

Customizing this loader

  • Color: set --ldr-color on the element or a parent. Currently previewing #3b82f6.
  • Size: set --ldr-size. Every dimension in the snippet is derived from it. Currently previewing 64px.
  • Speed: change the duration on the animation shorthand. Delays on the children are relative, so they keep their rhythm.
  • Accessibility: the root carries role="status" and an aria-label so screen readers announce the wait. The reduced-motion rule at the end slows the animation for users who asked for less motion.

Similar loaders