Loading
CSS-only shimmer animations for loading and placeholder states.
Basic skeleton
Combine skeleton shapes inside a .loading container. Children animate with staggered delays.
<div class="loading">
<div class="skeleton skeleton--heading"></div>
<div class="skeleton skeleton--text"></div>
<div class="skeleton skeleton--text"></div>
</div>
Shape variants
Use shape modifiers to match the content being loaded.
<div class="skeleton skeleton--heading"></div>
<div class="skeleton skeleton--text"></div>
<div class="skeleton skeleton--avatar"></div>
<div class="skeleton skeleton--image"></div>
Heading
Text
Avatar
Image
Card placeholder
Compose skeletons with layout primitives to match real content shapes.
<div class="card box stack loading">
<div class="cluster">
<div class="skeleton skeleton--avatar"></div>
<div class="skeleton skeleton--text" style="max-inline-size: 40%;"></div>
</div>
<div class="skeleton skeleton--text"></div>
<div class="skeleton skeleton--text"></div>
</div>
Animation pauses when prefers-reduced-motion is enabled.
Scoped requests
Send several requests to overlap them. The skeleton appears after 150 ms and stays visible for at least 300 ms. Cancellation and completion leave save status unknown. Only the separate simulated server response can confirm this example's result.
Replace content or remove the send button while a request is pending. Local state survives the update. Keep typing in the unrelated field or use the second operation.
First operation
This content receives local busy state.
Save status unknown. Nothing is persisted by this example.
Second operation
This content receives local busy state.
Save status unknown. Nothing is persisted by this example.
Server job state
A long-lived background stream does not belong to a finite request operation. This separate region simulates server-owned job state; it stays pending until a separate job update ends it.
Job output belongs to the server.
Server job idle.