Skeleton
A loading placeholder that is announced once and drawn as decoration.
Code
The three render the same class names, the same ARIA and the same data attributes. That is checked when this site builds: a class in any of these samples that neither the markup contract nor the shipped stylesheet defines fails the build.
<span class="wsu-skeleton" aria-hidden="true" style="display:block;inline-size:60%;block-size:1.5rem"></span>
<span class="wsu-sr-only" role="status">Loading</span>{{-- Server-rendered pages have nothing to skeleton. Use it in a Blade
page only where a fragment is fetched after first paint. --}}
<span class="wsu-skeleton" aria-hidden="true" style="display:block;block-size:1rem"></span><Skeleton width="60%" height="1.5rem" />
<Skeleton width="100%" height="1rem" label="" />
<Skeleton width="90%" height="1rem" label="" />Why it works this way
- The shape itself is aria-hidden. A screen reader reading twelve gray rectangles is worse than silence.
- A single visually hidden status carries the announcement. Set label to empty where a surrounding region already says it is loading.
- The shimmer respects prefers-reduced-motion through the global rule in base.css.
Accessibility
- Decoration is hidden (1.1.1).
- One polite status rather than one per shape (4.1.3).
Success criteria in brackets refer to WCAG 2.2. Every one of them is checked by axe-core in both themes at three viewport widths before this page can be published. See Accessibility for what the gates are.
Props
Blade
| Attribute | Default | What it does |
|---|---|---|
width | '100%' | Any CSS length. |
height | '1rem' | Any CSS length. |
label | 'Loading' | Announced once. Empty to stay silent. |
Vue
| Prop | Type and default | What it does |
|---|---|---|
width / height | String, '100%' / '1rem' | Any CSS length. |
label | String, 'Loading' | Announced once. Empty to stay silent. |