Feedback
Skeleton
Skeleton is temporary placeholder shapes that preserve layout while known content is loading.
Shape (Text/Circle/Rectangle) — 3 variants
betaReact AvailableFigma AvailableDocs Partial
- React last updated
- 2026-07-11
- Documentation last updated
- 2026-06-01
- Accessibility target
- WCAG 2.2 AA (target)
- Version
- 0.3.0-beta
Known open questions
- Composite skeleton layouts remain documentation examples until Figma confirms reusable list-item presets.
Live preview
Placeholder shapes that preserve layout while content loads.
Text / Circle / Rectangle
Loading container
Loading card content
Skeleton shapes are aria-hidden. The loading region uses aria-busy and screen-reader loading text. Shimmer animation respects prefers-reduced-motion.
Purpose
A placeholder shape mimicking the layout of content that hasn't loaded yet, reducing perceived load time and layout shift.
Anatomy
Skeleton = aria-hidden placeholder shape. SkeletonLoading wraps busy region + screen-reader loading label.
Variants and states
text · circle · rectangle
When to use
Any content area with a known layout shape whose real content takes a moment to load.
When not to use
Content with a genuinely unpredictable final shape/size.
Accessibility
aria-busy="true" on the container while loading; skeleton shapes themselves aria-hidden.
Keyboard behavior
Not interactive.
Common mistakes
Using a skeleton whose shape doesn't reasonably match the real content's eventual layout.
Properties
Shape as variants — composed together in a real "Skeleton List Item" example.
What is the difference between Skeleton and Spinner?
Skeleton preserves layout for known content shapes. Spinner signals activity without mimicking final layout.
Is Skeleton announced by screen readers?
Individual skeleton shapes are hidden. Provide loading text at the container level with aria-busy.
Tokens used
color/neutral/300
Component API
| Prop | Type | Default | Description |
|---|---|---|---|
| shape | "text" | "circle" | "rectangle" | "text" | Placeholder geometry. |
| width | string | number | — | Custom width. |
| height | string | number | — | Custom height. |
React example
Copy React example
import { Skeleton, SkeletonLoading } from "@/components/ui/Skeleton";
export function Example() {
return (
<SkeletonLoading
loading
loadingLabel="Loading profile"
skeleton={
<div style={{ display: "grid", gap: "0.5rem" }}>
<Skeleton shape="circle" />
<Skeleton shape="text" width="80%" />
<Skeleton shape="text" width="60%" />
</div>
}
>
<p>Loaded content</p>
</SkeletonLoading>
);
}