Skeleton
Placeholder shapes that match the final layout, so the page does not jump when content arrives.
In Dense data
See it live
npm run storybookWhen to use it
In Dense data: Rows while a table loads.
- Use it when: Lists, cards, dashboards and tables whose shape is known.
- Not when: A wait with no layout (spinner), or a region that loaded empty (empty).
Instead:
Words
- Lead with the object, then the state: "Alert 2041 contained."
- Use numbers, not words for numbers.
- One verb per button. No "please", no exclamation marks.
- Use: Investigate, Filter, Assign, Escalated, Resolved. Avoid: Oops, Awesome, Please, Simply.
The labels components use, from the voice tokens:
content.action.commit: Savecontent.action.cancel: Cancelcontent.action.destroy: Deletecontent.action.retry: Retrycontent.action.empty-action: Change filters
See Voice and tone for the whole voice.
Accessibility and keyboard
Test before you ship:
- The region says it is loading; the shapes themselves are hidden from screen readers. undefined
Use it in code
npx open-ds add skeleton
The component reads only component keys and semantic tokens, so it follows the brand and mode on <html>.
Tokens it reads
Skeleton reads 2 tokens of its own, each an alias of a semantic token. Each row is one part: its own token, the semantic it aliases, and the value it ends at. Change a semantic and every component that reads it follows; override one of Skeleton's tokens to change Skeleton alone.
Dense data decides what changes when you switch theme. Here a switch changes colors only, so the marked rows differ between light and dark; everything else holds steady.
| Part | Its token and the semantic it aliases | Value |
|---|---|---|
| Skeleton | ||
| Corner | component.skeleton.radiusradius.controlvar(--skeleton-radius) | radius.2:0.125rem |
| Fill Changes with theme | component.skeleton.backgroundcolor.surface.sunkenvar(--skeleton-background) | Lightslate.light.100:#EEF1F5Darkslate.dark.100:#262D38 |