Skip to content
roguelite labsAnthony Spezzano ↗
← Components

Loaders

8 loaders · Pure CSS · Copy & paste

Copy with intent. Each example is a standalone HTML/CSS study. Check its use case, integration and accessibility notes before dropping it into a real stateful flow.

8 examples

Spin Ring01

A compact indeterminate indicator beside a request that is still pending.

Inspect and copy source
Dependencies
None; HTML and CSS only.
Integration
Pair the visual with text that names what is pending and update that text when the operation finishes or fails.
Keyboard
The visual is not interactive; keep the surrounding cancel, retry, or navigation control keyboard reachable.
Status
Decorative animation alone does not announce progress. Add a nearby status element when this communicates pending work.
Reduced motion
The exported reduced-motion rule freezes the visual; keep a text status so the state remains clear.
Scope
The preview scopes the shared .component class per card. Scope or rename it before combining examples on one page.
<div class="component" aria-hidden="true"></div>

<style>
.component {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: 3px solid rgba(0,0,0,0.08);
  border-top-color: #111;
  animation: ldr-spin 0.7s linear infinite;
}
@keyframes ldr-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .component { animation: none; }
}
</style>

Dots02

A three-dot pending cue for short waits in a compact interface.

Inspect and copy source
Dependencies
None; HTML and CSS only.
Integration
Pair the visual with text that names what is pending and update that text when the operation finishes or fails.
Keyboard
The visual is not interactive; keep the surrounding cancel, retry, or navigation control keyboard reachable.
Status
Decorative animation alone does not announce progress. Add a nearby status element when this communicates pending work.
Reduced motion
The exported reduced-motion rule freezes the visual; keep a text status so the state remains clear.
Scope
The preview scopes the shared .component class per card. Scope or rename it before combining examples on one page.
<div class="component" aria-hidden="true"><span></span><span></span><span></span></div>

<style>
.component {
  display: flex;
  align-items: center;
  gap: 6px;
}
.component span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #111;
  animation: ldr-dots 1s ease-in-out infinite;
}
.component span:nth-child(2) { animation-delay: 0.15s; }
.component span:nth-child(3) { animation-delay: 0.3s; }
@keyframes ldr-dots {
  0%, 80%, 100% { transform: scale(1); opacity: 1; }
  40% { transform: scale(0.4); opacity: 0.3; }
}
@media (prefers-reduced-motion: reduce) {
  .component span { animation: none; opacity: 0.4; }
  .component span:nth-child(2) { opacity: 0.7; }
  .component span:nth-child(3) { opacity: 1; }
}
</style>

Bars03

A changing bar pattern for an active audio or signal state.

Inspect and copy source
Dependencies
None; HTML and CSS only.
Integration
Pair the visual with text that names what is pending and update that text when the operation finishes or fails.
Keyboard
The visual is not interactive; keep the surrounding cancel, retry, or navigation control keyboard reachable.
Status
Decorative animation alone does not announce progress. Add a nearby status element when this communicates pending work.
Reduced motion
The exported reduced-motion rule freezes the visual; keep a text status so the state remains clear.
Scope
The preview scopes the shared .component class per card. Scope or rename it before combining examples on one page.
<div class="component" aria-hidden="true"><span></span><span></span><span></span><span></span></div>

<style>
.component {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 28px;
}
.component span {
  width: 4px;
  background: #111;
  border-radius: 2px;
  animation: ldr-bars 1s ease-in-out infinite;
}
.component span:nth-child(1) { animation-delay: 0s; }
.component span:nth-child(2) { animation-delay: 0.12s; }
.component span:nth-child(3) { animation-delay: 0.24s; }
.component span:nth-child(4) { animation-delay: 0.36s; }
@keyframes ldr-bars {
  0%, 100% { height: 8px; }
  50% { height: 28px; }
}
@media (prefers-reduced-motion: reduce) {
  .component span { animation: none; height: 16px; }
}
</style>

Pulse04

A soft pulsing marker for presence or an ongoing background state.

Inspect and copy source
Dependencies
None; HTML and CSS only.
Integration
Pair the visual with text that names what is pending and update that text when the operation finishes or fails.
Keyboard
The visual is not interactive; keep the surrounding cancel, retry, or navigation control keyboard reachable.
Status
Decorative animation alone does not announce progress. Add a nearby status element when this communicates pending work.
Reduced motion
The exported reduced-motion rule freezes the visual; keep a text status so the state remains clear.
Scope
The preview scopes the shared .component class per card. Scope or rename it before combining examples on one page.
<div class="component" aria-hidden="true"></div>

<style>
.component {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #111;
  animation: ldr-pulse 1.2s ease-in-out infinite;
}
@keyframes ldr-pulse {
  0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(0.6); opacity: 0.35; }
}
@media (prefers-reduced-motion: reduce) {
  .component { animation: none; opacity: 0.6; }
}
</style>

Orbit05

A compact orbiting cue for work continuing without a determinate percentage.

Inspect and copy source
Dependencies
None; HTML and CSS only.
Integration
Pair the visual with text that names what is pending and update that text when the operation finishes or fails.
Keyboard
The visual is not interactive; keep the surrounding cancel, retry, or navigation control keyboard reachable.
Status
Decorative animation alone does not announce progress. Add a nearby status element when this communicates pending work.
Reduced motion
The exported reduced-motion rule freezes the visual; keep a text status so the state remains clear.
Scope
The preview scopes the shared .component class per card. Scope or rename it before combining examples on one page.
<div class="component" aria-hidden="true"><div class="component-track"><div class="component-dot"></div></div></div>

<style>
.component {
  width: 32px;
  height: 32px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.component::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: rgba(0,0,0,0.15);
  position: absolute;
}
.component-track {
  width: 32px;
  height: 32px;
  position: absolute;
  animation: ldr-orbit 1s linear infinite;
}
.component-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #111;
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
}
@keyframes ldr-orbit {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .component-track { animation: none; }
}
</style>

Ripple06

Expanding rings that make an active broadcast or waiting state visible.

Inspect and copy source
Dependencies
None; HTML and CSS only.
Integration
Pair the visual with text that names what is pending and update that text when the operation finishes or fails.
Keyboard
The visual is not interactive; keep the surrounding cancel, retry, or navigation control keyboard reachable.
Status
Decorative animation alone does not announce progress. Add a nearby status element when this communicates pending work.
Reduced motion
The exported reduced-motion rule freezes the visual; keep a text status so the state remains clear.
Scope
The preview scopes the shared .component class per card. Scope or rename it before combining examples on one page.
<div class="component" aria-hidden="true"><span></span><span></span><span></span></div>

<style>
.component {
  width: 36px;
  height: 36px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}
.component span {
  position: absolute;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  border: 2px solid #111;
  animation: ldr-ripple 1.6s ease-out infinite;
}
.component span:nth-child(2) { animation-delay: 0.5s; }
.component span:nth-child(3) { animation-delay: 1s; }
@keyframes ldr-ripple {
  0% { transform: scale(0.3); opacity: 1; }
  100% { transform: scale(1.3); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .component span:nth-child(2), .component span:nth-child(3) { display: none; }
  .component span { animation: none; transform: scale(0.8); }
}
</style>

Morph07

A shape morph for a playful indeterminate state in a noncritical wait.

Inspect and copy source
Dependencies
None; HTML and CSS only.
Integration
Pair the visual with text that names what is pending and update that text when the operation finishes or fails.
Keyboard
The visual is not interactive; keep the surrounding cancel, retry, or navigation control keyboard reachable.
Status
Decorative animation alone does not announce progress. Add a nearby status element when this communicates pending work.
Reduced motion
The exported reduced-motion rule freezes the visual; keep a text status so the state remains clear.
Scope
The preview scopes the shared .component class per card. Scope or rename it before combining examples on one page.
<div class="component" aria-hidden="true"></div>

<style>
.component {
  width: 28px;
  height: 28px;
  background: #111;
  animation: ldr-morph 1.4s ease-in-out infinite;
}
@keyframes ldr-morph {
  0%, 100% { border-radius: 4px; transform: rotate(0deg); }
  50% { border-radius: 50%; transform: rotate(180deg); }
}
@media (prefers-reduced-motion: reduce) {
  .component { animation: none; border-radius: 50%; }
}
</style>

Typing08

A typing cue shown beside a conversation while a reply is being prepared.

Inspect and copy source
Dependencies
None; HTML and CSS only.
Integration
Pair the visual with text that names what is pending and update that text when the operation finishes or fails.
Keyboard
The visual is not interactive; keep the surrounding cancel, retry, or navigation control keyboard reachable.
Status
Decorative animation alone does not announce progress. Add a nearby status element when this communicates pending work.
Reduced motion
The exported reduced-motion rule freezes the visual; keep a text status so the state remains clear.
Scope
The preview scopes the shared .component class per card. Scope or rename it before combining examples on one page.
<div class="component" aria-hidden="true"><span></span><span></span><span></span></div>

<style>
.component {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 7px 10px;
  background: rgba(0,0,0,0.06);
  border-radius: 14px;
}
.component span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(0,0,0,0.45);
  animation: ldr-typing 1.2s ease infinite;
}
.component span:nth-child(2) { animation-delay: 0.2s; }
.component span:nth-child(3) { animation-delay: 0.4s; }
@keyframes ldr-typing {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-4px); }
}
@media (prefers-reduced-motion: reduce) {
  .component span { animation: none; }
}
</style>