Skeleton
A skeleton holds the place of content that is still loading, as a gray shape sized like what will arrive. Choose text for a line of type and regular for a block, and the layout stays put when the content appears, with no reduced-motion code on your side. Below, a profile feed waits to load in every animation.
Reference docs
Choosing a loading indicator
Three kinds of indicator tell the reader to wait. Each suits a different job:
- Linear progress indicator: how far a task has got, or that it is still running, on a bar across the content, such as a file upload.
- Circular progress indicator: the same, in a compact ring, such as inside a button while it saves.
- Skeleton: the shape of content that is still loading, such as gray lines where a list will appear.
Two jobs belong elsewhere. A count or status on an icon is a badge, and a message once the work is done is a toast.
Choosing a variant
Two variants shape the placeholder to the content it replaces:
- Text: a line one
emhigh, for each line of a heading, a paragraph, or a caption. - Regular: a block that fills its parent, for an image, an avatar, or a card.
Built in
runs a wave unless your style configuration says otherwise;animation andpulse are the other two.none- A reader who asks for reduced motion sees a still placeholder, with no code on your side.
names the placeholder "Loading content" until you say what is loading.aria-label- Assistive technology is told the area is loading, with no code on your side.
Using skeletons well
- Draw one text skeleton for each line of text and one regular skeleton at the size of each image or card.
- Show the skeleton or the content, never both. Remove the skeleton when the content arrives.
- Say what is loading in each skeleton's label, such as "Loading profile".
- Put a regular skeleton in a parent that has a height.
Variants
A varianttextem high, so size it with font-size. A regularvariantregular
Children of a skeleton are never displayed.
Animation
animationwavepulsenonewave
In context
Show skeletons shaped like the content while it loads, then remove them. Give each an aria-labelrolestatus) and aria-busytrue) at their defaults, and assistive technology is told the area is loading.
Properties
| Property | Attribute | Type | Description |
|---|---|---|---|
animation | animationnone, pulse, wave | SkeletonAnimationSkeletonAnimation.None, .Pulse, .Wavedefault SkeletonAnimation.Wave, from the style configuration | Sets how the placeholder animates while loading. The animation stops for users who prefer reduced motion. See Animation. |
ariaBusy | aria-busy | stringdefault true | Tells a screen reader the placeholder is still loading. Set "false" to mark it as not busy. See In context. |
ariaLabel | aria-label | stringdefault Loading content | The name a screen reader announces for the placeholder. Set it to say what is loading. See In context. |
role | role | stringdefault status | The role assistive technology gives the placeholder. status makes it a polite live region. See In context. |
variant | variantregular, text | SkeletonVariantSkeletonVariant.Regular, .Textdefault SkeletonVariant.Regular, from the style configuration | Sets whether the placeholder is a line of text, 1em high, or a block that fills its container. See Variants. |
The skeleton has no width or height member, so CSS on the skeleton or its parent sizes it.
Props
| Prop | Type | Description |
|---|---|---|
animation | SkeletonAnimationTypeSkeletonAnimation.None, .Pulse, .Wavedefault SkeletonAnimation.Wave, from the style configuration | Sets how the placeholder animates while loading. The animation stops for users who prefer reduced motion. See Animation. |
ariaBusy | stringdefault true | Tells a screen reader the placeholder is still loading. Set "false" to mark it as not busy. See In context. |
variant | SkeletonVariantTypeSkeletonVariant.Regular, .Textdefault SkeletonVariant.Regular, from the style configuration | Sets whether the placeholder is a line of text, 1em high, or a block that fills its container. See Variants. |
The skeleton has no width or height member, so CSS on the skeleton or its parent sizes it.
Parameters
| Parameter | Type | Description |
|---|---|---|
Animation | SkeletonAnimation?SkeletonAnimation.None, .Pulse, .Wavedefault SkeletonAnimation.Wave, from the style configuration | Sets how the placeholder animates while loading. The animation stops for users who prefer reduced motion. See Animation. |
AriaBusy | string?default true | Tells a screen reader the placeholder is still loading. Set "false" to mark it as not busy. See In context. |
AriaLabel | string?default Loading content | The name a screen reader announces for the placeholder. Set it to say what is loading. See In context. |
Role | string?default status | The role assistive technology gives the placeholder. status makes it a polite live region. See In context. |
Variant | SkeletonVariant?SkeletonVariant.Regular, .Textdefault SkeletonVariant.Regular, from the style configuration | Sets whether the placeholder is a line of text, 1em high, or a block that fills its container. See Variants. |
The skeleton has no width or height member, so CSS on the skeleton or its parent sizes it.
Inputs
| Input | Type | Description |
|---|---|---|
animation | SkeletonAnimationTypeSkeletonAnimation.None, .Pulse, .Wavedefault SkeletonAnimation.Wave, from the style configuration | Sets how the placeholder animates while loading. The animation stops for users who prefer reduced motion. See Animation. |
ariaBusy | stringdefault true | Tells a screen reader the placeholder is still loading. Set "false" to mark it as not busy. See In context. |
ariaLabel | stringdefault Loading content | The name a screen reader announces for the placeholder. Set it to say what is loading. See In context. |
role | stringdefault status | The role assistive technology gives the placeholder. status makes it a polite live region. See In context. |
variant | SkeletonVariantTypeSkeletonVariant.Regular, .Textdefault SkeletonVariant.Regular, from the style configuration | Sets whether the placeholder is a line of text, 1em high, or a block that fills its container. See Variants. |
The skeleton has no width or height member, so CSS on the skeleton or its parent sizes it.
Props
| Prop | Type | Description |
|---|---|---|
animation | SkeletonAnimationTypeSkeletonAnimation.None, .Pulse, .Wavedefault SkeletonAnimation.Wave, from the style configuration | Sets how the placeholder animates while loading. The animation stops for users who prefer reduced motion. See Animation. |
ariaBusy | stringdefault true | Tells a screen reader the placeholder is still loading. Set "false" to mark it as not busy. See In context. |
ariaLabel | stringdefault Loading content | The name a screen reader announces for the placeholder. Set it to say what is loading. See In context. |
role | stringdefault status | The role assistive technology gives the placeholder. status makes it a polite live region. See In context. |
variant | SkeletonVariantTypeSkeletonVariant.Regular, .Textdefault SkeletonVariant.Regular, from the style configuration | Sets whether the placeholder is a line of text, 1em high, or a block that fills its container. See Variants. |
The skeleton has no width or height member, so CSS on the skeleton or its parent sizes it.
Props
| Prop | Type | Description |
|---|---|---|
animation | SkeletonAnimationTypeSkeletonAnimation.None, .Pulse, .Wavedefault SkeletonAnimation.Wave, from the style configuration | Sets how the placeholder animates while loading. The animation stops for users who prefer reduced motion. See Animation. |
ariaBusy | stringdefault true | Tells a screen reader the placeholder is still loading. Set "false" to mark it as not busy. See In context. |
ariaLabel | stringdefault Loading content | The name a screen reader announces for the placeholder. Set it to say what is loading. See In context. |
role | stringdefault status | The role assistive technology gives the placeholder. status makes it a polite live region. See In context. |
variant | SkeletonVariantTypeSkeletonVariant.Regular, .Textdefault SkeletonVariant.Regular, from the style configuration | Sets whether the placeholder is a line of text, 1em high, or a block that fills its container. See Variants. |
The skeleton has no width or height member, so CSS on the skeleton or its parent sizes it.
Each attribute value has its own tokens; a cell shows its token's value, and selecting the cell shows the token's fallback path, with each name and value ready to copy. For example, the regular column's corner-radius row is --ct-skeleton-regular-corner-radius, which defaults to --ct-sys-corner-radius-small.
Variant
| Name | regular | text |
|---|---|---|
corner-radius | --ct-sys-corner-radius-small --ct-skeleton-regular-corner-radius | --ct-sys-corner-radius-extra-small --ct-skeleton-text-corner-radius |
Other tokens
These stay the same whatever the variant.
| Token | Value |
|---|---|
--ct-skeleton-container-color | --ct-sys-color-on-surface --ct-skeleton-container-color |
--ct-skeleton-container-opacity | 0.16 --ct-skeleton-container-opacity |
--ct-skeleton-corner-radius | --ct-sys-corner-radius-small --ct-skeleton-corner-radius |
Names and states
A screen reader announces a skeleton with the ARIA status role, which ARIA defines as a polite live region. No WAI-ARIA Authoring Practices pattern covers a loading placeholder.
is the accessible name. It defaults to "Loading content"; set it per skeleton to say what is loading, such as "Loading profile".aria-label defaults torolestatus. defaults toaria-busytrueand also acceptsfalse.- Set the name, role, and busy state with
,aria-label , androle . Any other ARIA attribute on a skeleton has no effect.aria-busy - Remove the skeleton when the content arrives. Tell assistive technology the content has loaded, for example by placing it in a live region.
Keyboard and focus
| Key | Action |
|---|---|
| None | A skeleton takes no keyboard input. |
- It is not interactive: it takes no focus, fires no events, and passes clicks through to what is behind it.
Pointer and touch
- A skeleton is not a pointer target, so WCAG 2.5.8 Target Size (Minimum) has no touch target to measure.
Display settings
- Reduced motion: under a reduced-motion preference, the skeleton draws as
.none
Standards
With its defaults, a skeleton meets zero WCAG 2.2 success criteria on its own, because it takes no focus. Two depend on how you use it: