skeleton
A quiet, composable placeholder for consumer-owned loading states.
Example
Basic usage
<span id="profile-loading" role="status" data-visually-hidden>
Loading profile
</span>
<div aria-busy="true" aria-describedby="profile-loading">
<m-vstack gap="xs" aria-hidden="true">
<m-skeleton style="--skeleton-width: 62%"></m-skeleton>
<m-skeleton></m-skeleton>
<m-skeleton style="--skeleton-width: 42%"></m-skeleton>
</m-vstack>
</div>
API
m-skeleton is one contentless visual box. Consumers compose boxes to approximate their content and own every loading-state transition.
Content and loading contract
| Part | Contract | Default | Description |
|---|---|---|---|
| Skeleton | m-skeleton | required | An empty visual placeholder. Repeat it for multiple lines or blocks; it renders no generated content. |
| Placeholder group | aria-hidden="true" | consumer-owned | Hides the decorative skeleton composition from assistive technology. |
| Loading region | aria-busy | consumer-owned | Marks the content region while the application is replacing placeholders with real content. |
| Status message | role="status" | omitted | Optionally announces a meaningful loading label. Keep it outside an aria-hidden placeholder group. |
Styling
| Property | Value | Default | Description |
|---|---|---|---|
--skeleton-width | <length-percentage> | 100% | Sets the placeholder's inline size. |
--skeleton-height | <length-percentage> | 0.75rem | Sets the placeholder's block size. The default reads as one text line. |
--skeleton-radius | <length> | var(--radius-md) | Overrides the theme-following corner shape for a specific placeholder. |
Motion
| State | Treatment | Default | Description |
|---|---|---|---|
| Default | quiet pulse | 1.6s | Moves slowly between the raised-surface and border roles without a directional sweep. |
| Reduced motion | static fill | automatic | Disables animation and rests on the border color role. |
Accessibility
A skeleton is decorative and must not be the only indication that content is loading. Hide the placeholder composition with aria-hidden="true", mark the consumer-owned content region with aria-busy="true", and provide a concise status message when the loading transition needs an announcement. When content arrives, replace the placeholders and clear aria-busy; m-skeleton emits no events and manages no state.
Notes
Match placeholder dimensions to the expected content to reduce layout shift. Compose repeated elements rather than asking one skeleton to generate a line count. Mica supplies no circle or avatar variant: the default follows the theme radius, and a consumer can set --skeleton-radius when the represented content requires a different shape.