Skeleton
Loading placeholder block that respects reduced motion.
import { Skeleton } from '@elirobinson/react/components/atoms/Skeleton';Styles: @elirobinson/react/styles/atoms/Skeleton.css — already included when you import @elirobinson/react/styles.css.
Show code
import { Skeleton } from '@elirobinson/react/components/atoms/Skeleton';
export default function Basic() {
return <Skeleton style={{ width: 240, height: 20 }} />;
}When to use it
Use Skeleton for a structural loading placeholder that mimics the shape of the content
about to appear — it cuts layout shift and signals progress visually. Use Spinner
instead for a small, content-agnostic "working" indicator, and Progress when you
actually know the percent complete.
Composing a loading card
Stack skeletons to match the real content's layout — an image block, a title line, a subtitle line.
Show code
import { Skeleton } from '@elirobinson/react/components/atoms/Skeleton';
export default function Card() {
return (
<div className="demo-col" aria-label="Loading coaching guides" role="status">
<Skeleton style={{ height: 160 }} />
<Skeleton style={{ height: 16, width: '80%' }} />
<Skeleton style={{ height: 14, width: '60%' }} />
</div>
);
}Props
Skeleton has no props of its own — size and shape come from className/style on the
inherited HTMLAttributes<HTMLDivElement>.
No props of its own beyond the inherited HTML attributes.
Also accepts all HTMLAttributes<HTMLDivElement> props.
Accessibility
- Always renders with
aria-hidden="true"— it's invisible to screen readers by design, meaning it does not announce a loading state to assistive tech on its own. - If the wait is long enough to matter, pair it with a
role="status"wrapper or visually-hidden text (see the card demo above), or useSpinner, which already carriesrole="status". - The pulse animation respects
prefers-reduced-motion— not through a per-component check, but because the design tokens stylesheet flattens all animation and transition durations globally when that preference is set.
Do
- Shape skeletons to match the real content’s dimensions so the swap-in doesn’t jump.
- Stack multiple Skeletons to represent a whole loading card, mirroring the real layout.
- Pair it with a role="status" wrapper or screen-reader-only text when the wait genuinely needs to be announced.
Don't
- Rely on Skeleton alone to tell screen reader users something is loading — it’s aria-hidden, silent by design.
- Leave skeletons on screen indefinitely if a request fails — swap to an error state, don’t strand the pulse.
- Use Skeleton for a single small icon-sized loading state — Spinner reads better at that scale.