AI CSS Animations

Signal Strength Loader

Four rising bars fill from the bottom one after another, then drain in the same order, the phone signal icon searching for reception. Good for connect, sync and reconnect states.

Also known as: cell signal loader, network bars animation, reception bars.

HTML

<div class="ldr-signal-strength" role="status" aria-label="Connecting">
  <span></span><span></span><span></span><span></span>
</div>

CSS

.ldr-signal-strength {
  --s: var(--ldr-size, 48px);
  --c: var(--ldr-color, #3b82f6);
  display: flex;
  align-items: flex-end;
  gap: calc(var(--s) / 10);
  width: var(--s);
  height: var(--s);
}
.ldr-signal-strength span {
  position: relative;
  flex: 1;
  overflow: hidden;
  border-radius: calc(var(--s) / 20);
  background: color-mix(in srgb, var(--ldr-color, #3b82f6) 18%, transparent);
}
.ldr-signal-strength span::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--c);
  transform: scaleY(0);
  transform-origin: 50% 100%;
  animation: ldr-signal-strength-fill 2s infinite;
}
.ldr-signal-strength span:nth-child(1) { height: 30%; }
.ldr-signal-strength span:nth-child(2) { height: 53%; }
.ldr-signal-strength span:nth-child(3) { height: 76%; }
.ldr-signal-strength span:nth-child(4) { height: 100%; }
.ldr-signal-strength span:nth-child(2)::before { animation-delay: 0.2s; }
.ldr-signal-strength span:nth-child(3)::before { animation-delay: 0.4s; }
.ldr-signal-strength span:nth-child(4)::before { animation-delay: 0.6s; }
@keyframes ldr-signal-strength-fill {
  0%   { transform: scaleY(0); opacity: 1; animation-timing-function: cubic-bezier(0.3, 0.7, 0.4, 1); }
  15%  { transform: scaleY(1); opacity: 1; }
  54%  { transform: scaleY(1); opacity: 1; }
  66%  { transform: scaleY(1); opacity: 0; }
  66.1%, 100% { transform: scaleY(0); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ldr-signal-strength, .ldr-signal-strength *, .ldr-signal-strength::before, .ldr-signal-strength::after, .ldr-signal-strength *::before, .ldr-signal-strength *::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