AI CSS Animations

Avatar Loading Ring Spinner

Two arcs circle a placeholder avatar while the silhouette inside breathes, for profile pictures, chat heads and user cards that are still loading. The person glyph is drawn inline in the same SVG.

Also known as: profile picture loading ring, story ring animation, avatar placeholder spinner.

HTML

<svg class="ldr-avatar-ring" viewBox="0 0 48 48" role="status" aria-label="Loading profile">
  <circle class="ldr-avatar-ring-arcs" cx="24" cy="24" r="22" pathLength="100"></circle>
  <g class="ldr-avatar-ring-face">
    <circle cx="24" cy="24" r="17"></circle>
    <circle cx="24" cy="19.5" r="6"></circle>
    <path d="M12 36.3A12.5 10 0 0 1 36 36.3A17 17 0 0 1 12 36.3Z"></path>
  </g>
</svg>

CSS

.ldr-avatar-ring {
  --s: var(--ldr-size, 48px);
  --c: var(--ldr-color, #3b82f6);
  width: var(--s);
  height: var(--s);
}
.ldr-avatar-ring-arcs {
  fill: none;
  stroke: var(--c);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: 30 20;
  transform-origin: center;
  animation: ldr-avatar-ring-spin 1.4s linear infinite;
}
.ldr-avatar-ring-face circle:first-child {
  fill: color-mix(in srgb, var(--ldr-color, #3b82f6) 14%, transparent);
}
.ldr-avatar-ring-face circle + circle,
.ldr-avatar-ring-face path {
  fill: color-mix(in srgb, var(--ldr-color, #3b82f6) 38%, transparent);
  animation: ldr-avatar-ring-breathe 1.4s ease-in-out infinite alternate;
}
@keyframes ldr-avatar-ring-spin {
  to { transform: rotate(360deg); }
}
@keyframes ldr-avatar-ring-breathe {
  from { opacity: 1; }
  to   { opacity: 0.45; }
}

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