Feedback
Skeleton
Usage#
import { WdsSkeletonComponent } from '@wds/angular/skeleton';h-4 w-48, size-12) to match the content it stands for. Without a height a skeleton is one line of text tall.
Examples#
Default#
shape="circle" makes a round placeholder (e.g. for an avatar); set one dimension, the other follows.
import { Component } from '@angular/core';
import { WdsSkeletonComponent } from '@wds/angular/skeleton';
@Component({
selector: 'app-skeleton-default-demo',
imports: [WdsSkeletonComponent],
template: `
<div class="flex items-center gap-4">
<wds-skeleton shape="circle" class="size-12"></wds-skeleton>
<div class="grid gap-2">
<wds-skeleton class="h-4 w-[250px]"></wds-skeleton>
<wds-skeleton class="h-4 w-[200px]"></wds-skeleton>
</div>
</div>
`,
})
export class SkeletonDefaultDemo {}Card#
aria-busy="true" and a visually hidden "Loading…", because skeletons are hidden from screen readers. Classes on the skeleton (rounded-xl, aspect-video) change its shape.
import { Component } from '@angular/core';
import { WdsSkeletonComponent } from '@wds/angular/skeleton';
@Component({
selector: 'app-skeleton-card-demo',
imports: [WdsSkeletonComponent],
template: `
<div class="flex w-full max-w-xs flex-col gap-3" aria-busy="true">
<span class="sr-only">Loading…</span>
<wds-skeleton class="aspect-video h-auto w-full rounded-xl"></wds-skeleton>
<wds-skeleton class="h-4 w-3/4"></wds-skeleton>
<wds-skeleton class="h-4 w-1/2"></wds-skeleton>
</div>
`,
})
export class SkeletonCardDemo {}Text#
import { Component } from '@angular/core';
import { WdsSkeletonComponent } from '@wds/angular/skeleton';
@Component({
selector: 'app-skeleton-text-demo',
imports: [WdsSkeletonComponent],
template: `
<div class="flex w-full max-w-md flex-col gap-2 text-sm">
<wds-skeleton class="mb-2 h-6 w-1/3"></wds-skeleton>
<wds-skeleton></wds-skeleton>
<wds-skeleton></wds-skeleton>
<wds-skeleton></wds-skeleton>
<wds-skeleton class="w-2/3"></wds-skeleton>
</div>
`,
})
export class SkeletonTextDemo {}Form#
import { Component } from '@angular/core';
import { WdsSkeletonComponent } from '@wds/angular/skeleton';
@Component({
selector: 'app-skeleton-form-demo',
imports: [WdsSkeletonComponent],
template: `
<div class="flex w-full max-w-sm flex-col gap-6">
<div class="grid gap-2">
<wds-skeleton class="h-4 w-20"></wds-skeleton>
<wds-skeleton class="h-9 w-full"></wds-skeleton>
</div>
<div class="grid gap-2">
<wds-skeleton class="h-4 w-24"></wds-skeleton>
<wds-skeleton class="h-9 w-full"></wds-skeleton>
</div>
<wds-skeleton class="h-9 w-28 self-start"></wds-skeleton>
</div>
`,
})
export class SkeletonFormDemo {}Table#
import { Component } from '@angular/core';
import { WdsSkeletonComponent } from '@wds/angular/skeleton';
@Component({
selector: 'app-skeleton-table-demo',
imports: [WdsSkeletonComponent],
template: `
<div class="flex w-full max-w-lg flex-col rounded-lg border border-border">
<div class="grid grid-cols-[2fr_1fr_1fr] gap-4 border-b border-border p-3">
<wds-skeleton class="h-4 w-24"></wds-skeleton>
<wds-skeleton class="h-4 w-16"></wds-skeleton>
<wds-skeleton class="h-4 w-12 justify-self-end"></wds-skeleton>
</div>
<div class="grid grid-cols-[2fr_1fr_1fr] items-center gap-4 border-b border-border p-3">
<div class="flex items-center gap-3">
<wds-skeleton shape="circle" class="size-8"></wds-skeleton>
<wds-skeleton class="h-4 w-28"></wds-skeleton>
</div>
<wds-skeleton class="h-5 w-16 rounded-full"></wds-skeleton>
<wds-skeleton class="h-4 w-14 justify-self-end"></wds-skeleton>
</div>
<div class="grid grid-cols-[2fr_1fr_1fr] items-center gap-4 border-b border-border p-3">
<div class="flex items-center gap-3">
<wds-skeleton shape="circle" class="size-8"></wds-skeleton>
<wds-skeleton class="h-4 w-36"></wds-skeleton>
</div>
<wds-skeleton class="h-5 w-16 rounded-full"></wds-skeleton>
<wds-skeleton class="h-4 w-14 justify-self-end"></wds-skeleton>
</div>
<div class="grid grid-cols-[2fr_1fr_1fr] items-center gap-4 p-3">
<div class="flex items-center gap-3">
<wds-skeleton shape="circle" class="size-8"></wds-skeleton>
<wds-skeleton class="h-4 w-24"></wds-skeleton>
</div>
<wds-skeleton class="h-5 w-16 rounded-full"></wds-skeleton>
<wds-skeleton class="h-4 w-14 justify-self-end"></wds-skeleton>
</div>
</div>
`,
})
export class SkeletonTableDemo {}Stats#
import { Component } from '@angular/core';
import { WdsSkeletonComponent } from '@wds/angular/skeleton';
@Component({
selector: 'app-skeleton-stats-demo',
imports: [WdsSkeletonComponent],
template: `
<div class="flex w-full max-w-2xl flex-col gap-4 sm:flex-row">
<div class="grid flex-1 gap-3 rounded-lg border border-border p-4">
<wds-skeleton class="h-4 w-24"></wds-skeleton>
<wds-skeleton class="h-8 w-20"></wds-skeleton>
<wds-skeleton class="h-3 w-32"></wds-skeleton>
</div>
<div class="grid flex-1 gap-3 rounded-lg border border-border p-4">
<wds-skeleton class="h-4 w-24"></wds-skeleton>
<wds-skeleton class="h-8 w-20"></wds-skeleton>
<wds-skeleton class="h-3 w-32"></wds-skeleton>
</div>
<div class="grid flex-1 gap-3 rounded-lg border border-border p-4">
<wds-skeleton class="h-4 w-24"></wds-skeleton>
<wds-skeleton class="h-8 w-20"></wds-skeleton>
<wds-skeleton class="h-3 w-32"></wds-skeleton>
</div>
</div>
`,
})
export class SkeletonStatsDemo {}Animation#
animation is pulse (default), wave (a light passes over the placeholder) or none. With "reduce motion" turned on in the system, skeletons do not animate.
import { Component } from '@angular/core';
import { WdsSkeletonComponent } from '@wds/angular/skeleton';
@Component({
selector: 'app-skeleton-animation-demo',
imports: [WdsSkeletonComponent],
template: `
<div class="flex w-full max-w-sm flex-col gap-4 text-sm">
<div class="grid gap-2">
<span class="text-muted-foreground">pulse (default)</span>
<wds-skeleton class="h-10"></wds-skeleton>
</div>
<div class="grid gap-2">
<span class="text-muted-foreground">wave</span>
<wds-skeleton animation="wave" class="h-10"></wds-skeleton>
</div>
<div class="grid gap-2">
<span class="text-muted-foreground">none</span>
<wds-skeleton animation="none" class="h-10"></wds-skeleton>
</div>
</div>
`,
})
export class SkeletonAnimationDemo {}API References#
wds-skeleton#
h-4 w-48 classes);
without a height it is as tall as a line of text.
A skeleton is hidden from screen readers. Mark the loading region with aria-busy="true" and give it a
text alternative, e.g. a visually hidden "Loading…".
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
| shape | WdsSkeletonShape | 'default' | circle: round, with equal width and height (set one of them), e.g. for an avatar. |
| animation | WdsSkeletonAnimation | 'pulse' | pulse fades in and out, wave passes a light over the placeholder, none stays still. |
CSS parts (::part)
| Part | Description |
|---|---|
| base |
CSS custom properties
| Property | Description |
|---|---|
| --wds-skeleton-bg | --wds-accent). |
| --wds-skeleton-highlight | wave animation. |
| --wds-skeleton-radius | --wds-radius-md). |
Accessibility#
Screen reader#
aria-hidden="true"): they only show the shape of the content.
aria-busy="true" and give it a text alternative, e.g. a visually hidden "Loading…". Remove aria-busy when the content is there.