Skeleton
A shimmering placeholder shaped like the content it stands in for. Use whenever a response takes longer than 300 ms — the operator stays oriented because the layout has already settled.
Shapes
Four primitives — text line, circle, rectangle, and card. Compose them to mirror the real layout.
Table placeholder
Mirrors the row count and column widths so the page doesn't jump when data lands.
| Receipt | Till | Cashier | Total |
|---|---|---|---|
List row composition
Avatar + two text rows. Mirror the real row's vertical rhythm.
Parts
| Property | Value | Notes |
|---|---|---|
| fill | linear-gradient muted → sunken → muted | Animated 1.4 s loop |
| radius | 6 px default | 9999 for circles · 10 px for cards |
| text height | 10 / 12 / 14 px | Match the real type scale |
| animation | cor-skel · 1.4 s ease-in-out | Honours prefers-reduced-motion |
| hold time | Show after 300 ms | Skip if response is faster |
Do & don't
Mirror the real layout — same row count, same column widths. The page should not reflow when data arrives.
Use a single spinner for content over 200 px tall. The operator loses orientation.
Vary line widths (100 % / 80 % / 60 %) so the placeholder reads as text, not as a brick.
Show a skeleton for under 300 ms. The flash distracts more than it helps.
Code
<!-- Text lines --> <div class="skeleton" style="height: 12px; width: 80%;"></div> <!-- Circle (avatar) --> <div class="skeleton" style="height: 36px; width: 36px; border-radius: 9999px;"></div> <!-- Card --> <div class="skeleton" style="height: 140px; border-radius: 10px;"></div>
Related
For indeterminate spinners under 300 ms, see Spinner. For the loading/error/empty triad, see Empty & loading flows.