All components (204)
Skeleton
Surfaces · Skeleton · .amset-skeleton
What it is and when to use it
A gray placeholder, with a shine that passes over it, while the content arrives. It holds the place with the shape of what is going to arrive (lines of text, a title, a block, a circle), so that the page does not jump on load.
When to use it
- Loads of more than an instant where the shape of what is coming is known: a list, a detail page, a card.
shape="text"(default) drawslineslines, with the last one shorter;title,blockandcircleare a single piece.size(fromxstoxl) gives it the thickness of a text of that size and, incircle, the side of theAvatarof the same size: the slot does not jump when the photo arrives.width,heightandradiusto fit it to what it replaces (an avatar, a photo, a card). Intext, the width is that of the paragraph and the height and the radius are those of each line.
When not to
- A task that advances and ends (uploading a file, importing):
Progress. - Waiting for a button to respond:
Buttonwithloading. - A dashboard figure:
Statwithloading, which already reserves the slot of the number.
Keyboard: it is not focusable.
Accessibility: it is decorative on purpose (aria-hidden): hearing "image, image, image" helps nobody. What says that something is loading is the container, with aria-busy (Card sets it with loading), or a status text. With reduced motion it stays still and without shine; withoutAnimation keeps it still always, in all shapes (in text, all the lines).
Fine-tuning: CSS variables --amset-skeleton-*: -duration (one pass of the shine, two turns of --amset-duration-spin), -color (10% of the ink over whatever is behind: it looks the same over the background, over a card or over an alternate row), -shine, -radius, -line, -title and -circle. In md: line of 0.75rem, title of 1.25rem at 40% of the width, block of 8rem and circle of 2.25rem, that of the avatar. The shine moves with transform, without repainting.
What it looks like
<Skeleton shape="title" width="12ch" />
<Skeleton shape="text" lines={3} />Props
Import it with import { Skeleton } from '@amset/ui'. Required props are marked.
| Prop | Type | What it does |
|---|---|---|
className | string | Merged with the library classes; it does not replace them. |
height | string | Height of the gap; in the `text` shape, that of each line. |
lines | number | How many lines, for the `text` shape. The last one comes out shorter. |
radius | string | Own radius: to match the card or avatar it replaces. In the `text` shape, that of each line. |
shape | SkeletonShape | — |
size | "sm" | "md" | "lg" | "xs" | "xl" | What it stands in for, at the same size: the thickness of the lines of `text` and `title`, and the diameter of the `circle`, which is that of the `Avatar` of the same size (so the space does not jump when the photo arrives). |
width | string | Width of the gap; in the `text` shape, that of the whole paragraph. |
withoutAnimation | boolean | Still, with no shimmer; in the `text` shape, all the lines. With reduced motion it already stays still on its own. |
It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.
CSS variables
These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.
| Variable | Default |
|---|---|
--amset-skeleton-duration | calc(var(--amset-duration-spin) * 2) |
--amset-skeleton-color | color-mix(in oklab, var(--amset-ink) 10%, transparent) |
--amset-skeleton-shine | color-mix(in oklab, var(--amset-surface) 55%, transparent) |
--amset-skeleton-radius | var(--amset-radius-sm) |
--amset-skeleton-line | 0.75rem |
--amset-skeleton-title | 1.25rem |
--amset-skeleton-circle | 2.25rem |
How to change it
.amset-skeleton {
--amset-skeleton-duration: ...;
--amset-skeleton-color: ...;
}In the test bench
Every state and variant, to try one at a time, on its page at ui.amset.tech:
