interactionintermediate

Avatar Animation

Animated states on user avatar images or initials that communicate presence, status, recording state, and identity transitions.

Plain English

Static avatars are identity. Animated avatars are presence. The green dot on a LinkedIn profile does not just tell you someone is online — the pulsing version tells you they are active right now. A ring animation on an Instagram story tells you 'there is something new here, look'. A softly pulsing red ring on a face in a video call tells you you are live. These animations carry meaning that words would take three times as long to communicate. The design rules are tight: avatar animations must be small (never distract from content), purposeful (tied to real state), and immediately comprehensible (a pulse means active, a spin means loading, a ring means 'something is here').

Technical

Implement via CSS keyframes on a ring/border element layered over the avatar img. For the online pulse: a ::after pseudo-element at bottom-right, 10×10px, background: green, border-radius: 50%, with a scale+opacity pulse animation (1s ease-in-out infinite). For story rings: conic-gradient border on the avatar container, rotating via CSS animation. For skeleton→reveal: use a shimmer animation on a placeholder div, swap to the real img on load with a 200ms fade-in. For recording: red ring + pulsing scale (1.0→1.06→1.0, 1.5s). Always define all animations in motion-safe: {} in Tailwind or inside @media (prefers-reduced-motion: no-preference) {}.

Live Demo

Avatar animation states

Loading
Skeleton shimmer → photo reveal on load
AH
Online
Green pulse dot — "active now"
RK
Recording
Red ring pulse — live or recording screen
JS
New story
Gradient ring — unread content available
TL
Away
Dimmed + yellow dot — present but inactive
MW
Offline
Static grey dot — no animation, no presence

All animations respect prefers-reduced-motion — the pulse and spin stop when reduced motion is set

Usage

✓ Good usage

A collaborative editing header showing team member avatars with: static grey for offline, subtle green pulse for online, animated red ring for "currently recording screen", skeleton shimmer while avatar URLs load — all communicating real-time state at a glance.

✗ Bad usage

An avatar that spins continuously to show it is "your account" or pulses green permanently regardless of actual online status — animation without information is noise.

Common mistakes

AI Prompt Example

Copy this into Claude, Cursor, Bolt, or v0.

Implement avatar status animation: wrap the avatar img in a relative-positioned container. Add a ::after pseudo-element (or a span) positioned bottom-right at 11×11px for status dot. Online: bg-green-500 with @keyframes pulse (scale 1→1.4→1, opacity 1→0.6→1, 2s infinite). Recording: replace dot with a 2px solid red ring on the avatar border, @keyframes recording-pulse (scale 1→1.05→1, 1.5s infinite). Skeleton: show a shimmer div (bg-gradient shimmer keyframe) until the img onLoad fires. All animations wrapped in @media (prefers-reduced-motion: no-preference).