Skeleton
Directive that applies a non-semantic placeholder treatment to an existing element while known content is loading.
Import the public directive from the published package entrypoint.
import { KuiSkeleton } from '@kikita-labs/ui';Apply kuiSkeleton to placeholder elements inside a region marked aria-busy. Skeleton hosts are automatically aria-hidden.
<article kuiCard class="skeleton-composition-example" aria-busy="true">
<div class="skeleton-composition-example__row">
<span kuiSkeleton shape="circle" style="inline-size: 40px"></span>
<div class="skeleton-composition-example__stack">
<span kuiSkeleton shape="heading" style="inline-size: 45%"></span>
<span kuiSkeleton shape="text" style="inline-size: 70%"></span>
</div>
</div>
<div class="skeleton-composition-example__stack">
<span kuiSkeleton shape="text" style="inline-size: 100%"></span>
<span kuiSkeleton shape="text" style="inline-size: 88%"></span>
<span kuiSkeleton shape="text" style="inline-size: 64%"></span>
</div>
<span kuiSkeleton shape="button" style="inline-size: 100%"></span>
</article>shape maps to Kikita UI skeleton geometry tokens for common placeholder layouts.
textheadingrectcirclesquarebuttonbadge<div class="skeleton-shapes-example">
<div class="skeleton-shapes-example__item">
<span kuiSkeleton shape="text" style="inline-size: 140px"></span>
<code>text</code>
</div>
<div class="skeleton-shapes-example__item">
<span kuiSkeleton shape="heading" style="inline-size: 180px"></span>
<code>heading</code>
</div>
<div class="skeleton-shapes-example__item">
<span kuiSkeleton shape="rect" style="inline-size: 140px; block-size: 64px"></span>
<code>rect</code>
</div>
<div class="skeleton-shapes-example__item">
<span kuiSkeleton shape="circle" style="inline-size: 40px"></span>
<code>circle</code>
</div>
<div class="skeleton-shapes-example__item">
<span kuiSkeleton shape="square" style="inline-size: 40px"></span>
<code>square</code>
</div>
<div class="skeleton-shapes-example__item">
<span kuiSkeleton shape="button" style="inline-size: 96px"></span>
<code>button</code>
</div>
<div class="skeleton-shapes-example__item">
<span kuiSkeleton shape="badge" style="inline-size: 64px"></span>
<code>badge</code>
</div>
</div>animation controls the placeholder motion. Defaults to shimmer; use pulse or none for quieter surfaces.
shimmer (default)pulsenone<div class="skeleton-animation-example">
<div class="skeleton-animation-example__stack">
<span kuiSkeleton shape="heading" style="inline-size: 60%"></span>
<span kuiSkeleton shape="text" style="inline-size: 100%"></span>
<span kuiSkeleton shape="text" style="inline-size: 80%"></span>
<code>shimmer (default)</code>
</div>
<div class="skeleton-animation-example__stack">
<span kuiSkeleton shape="heading" animation="pulse" style="inline-size: 60%"></span>
<span kuiSkeleton shape="text" animation="pulse" style="inline-size: 100%"></span>
<span kuiSkeleton shape="text" animation="pulse" style="inline-size: 80%"></span>
<code>pulse</code>
</div>
<div class="skeleton-animation-example__stack">
<span kuiSkeleton shape="heading" animation="none" style="inline-size: 60%"></span>
<span kuiSkeleton shape="text" animation="none" style="inline-size: 100%"></span>
<span kuiSkeleton shape="text" animation="none" style="inline-size: 80%"></span>
<code>none</code>
</div>
</div>Combine skeleton shapes to mirror the loaded layout. Put aria-busy on the parent region, not on each skeleton block.
<article kuiCard class="skeleton-composition-example" aria-busy="true">
<div class="skeleton-composition-example__row">
<span kuiSkeleton shape="circle" style="inline-size: 40px"></span>
<div class="skeleton-composition-example__stack">
<span kuiSkeleton shape="heading" style="inline-size: 45%"></span>
<span kuiSkeleton shape="text" style="inline-size: 70%"></span>
</div>
</div>
<div class="skeleton-composition-example__stack">
<span kuiSkeleton shape="text" style="inline-size: 100%"></span>
<span kuiSkeleton shape="text" style="inline-size: 88%"></span>
<span kuiSkeleton shape="text" style="inline-size: 64%"></span>
</div>
<span kuiSkeleton shape="button" style="inline-size: 100%"></span>
</article>Set defaults.skeleton once for the application or for a subtree. Each option resolves as local input > defaults.skeleton.<option> > built-in default.
import { provideKikitaUi } from '@kikita-labs/ui';
export const appConfig: ApplicationConfig = {
providers: [
provideKikitaUi({
defaults: {
skeleton: {
/* options below */
},
},
}),
],
};| Name | Type | Default | Description |
|---|---|---|---|
| shape | 'text' | 'heading' | 'rect' | 'circle' | 'square' | 'button' | 'badge' | — | Default shape. |
| animation | 'shimmer' | 'pulse' | 'none' | — | Default animation. |
Set any of these on the component or an ancestor to restyle one part. Each token is optional: when it is not set, the part uses the role or scale token in the default column.
| Name | Type | Default | Description |
|---|---|---|---|
| --kui-skeleton-radius-text | CSS custom property | --kui-radius-xs | Corner radius, text |
| --kui-skeleton-radius-heading | CSS custom property | --kui-radius-xs | Corner radius, heading |
| --kui-skeleton-radius-button | CSS custom property | --kui-radius-md | Corner radius, button |
Inputs verified against @kikita-labs/ui v2.0.0 public typings.
| Name | Type | Default | Description |
|---|---|---|---|
| shape | 'text' | 'heading' | 'rect' | 'circle' | 'square' | 'button' | 'badge' | undefined | undefined | Placeholder shape mapped to Kikita UI skeleton geometry tokens. Falls back to defaults.skeleton.shape, then rect. |
| animation | 'shimmer' | 'pulse' | 'none' | undefined | undefined | Placeholder animation mode (defaults.skeleton.animation, then shimmer). Automatically disabled when the user prefers reduced motion, regardless of this value. |
| KuiSkeletonOptions | interface | - | Shape of defaults.skeleton: shape and animation. |
Skeleton is decorative placeholder chrome, not an announced loading status.
- Skeleton hosts are automatically
aria-hidden="true"and must not expose text to assistive technology. - Put
aria-busy="true"on the loading region, not on every skeleton block. - Do not make skeleton hosts focusable or interactive.
- Use
kuiLoaderinstead when the UI needs an announced loading status. - Kikita disables skeleton animation under
prefers-reduced-motionregardless of the configuredanimationvalue.
Consumer-visible changes of @kikita-labs/ui 2.0 for Skeleton.
- The directive class is
KuiSkeleton; theDirectivesuffix is gone. - Shape and animation defaults moved to
provideKuiDefaults({ skeleton: { shape, animation } }); the inputs are nowundefineduntil set. - The host-level pulse animation is disabled under reduced motion as well as the shimmer.
- Skeleton colours derive from
seeds.neutral, and the text, heading and button corner radii have geometry tokens.