Bouncing dots
Three dots bounce in sequence, the familiar typing or thinking indicator.
CSSBeginner
<div class="bubble" role="status" aria-label="Typing"><span class="dot" style="--i:0"></span><span class="dot" style="--i:1"></span><span class="dot" style="--i:2"></span></div>
.bubble{display:flex;gap:7px;padding:16px 20px;border-radius:20px 20px 20px 6px;background:#2e1b19}
.dot{width:10px;height:10px;border-radius:50%;background:#f08a5d;animation:bounce 1.1s ease-in-out infinite;animation-delay:calc(var(--i) * .15s)}
@keyframes bounce{0%,60%,100%{transform:translateY(0);opacity:.5}30%{transform:translateY(-9px);opacity:1}}
@media (prefers-reduced-motion:reduce){.dot{animation:none}}
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Bouncing dots</title>
<style>
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{display:grid;place-items:center;background:#140807;color:#fffffc;font:16px/1.5 system-ui,-apple-system,"Segoe UI",sans-serif}
.bubble{display:flex;gap:7px;padding:16px 20px;border-radius:20px 20px 20px 6px;background:#2e1b19}
.dot{width:10px;height:10px;border-radius:50%;background:#f08a5d;animation:bounce 1.1s ease-in-out infinite;animation-delay:calc(var(--i) * .15s)}
@keyframes bounce{0%,60%,100%{transform:translateY(0);opacity:.5}30%{transform:translateY(-9px);opacity:1}}
@media (prefers-reduced-motion:reduce){.dot{animation:none}}
</style></head>
<body>
<div class="bubble" role="status" aria-label="Typing"><span class="dot" style="--i:0"></span><span class="dot" style="--i:1"></span><span class="dot" style="--i:2"></span></div>
</body></html>
Good for
Chat typing indicators, AI replies and short waits.
Watch out for
Use animation-delay on each dot, not three separate keyframes, so timing stays easy to tune.
Accessibility
Wrap motion in @media (prefers-reduced-motion: reduce) and switch it off or shorten it for people who ask for less movement.