Skip to content

Skeleton loader

wu-skeleton is a placeholder shape shown while content loads. The default shape is a block; text and circle change it.

Placeholders are decoration: add aria-hidden="true" to each skeleton, and aria-busy="true" with visible or hidden “Loading” text on the region being loaded. Remove both when the content arrives.

Class or variable Effect
wu-skeleton Root. Full width block, 6rem high, in a still tint
text One line of text; the last of several lines is shorter
circle Circle, 2.5rem
animated Shimmer sweep, opt-in (see Animation)
--wu-skeleton--Width, --wu-skeleton--Height Block and line size
--wu-skeleton--Size Circle size

By default the shapes are still. The shimmer is opt-in, like all motion in the kit.

Loading
<div aria-busy="true">
<span class="sr-only">Loading</span>
<div class="wu-skeleton" aria-hidden="true"></div>
</div>
Loading
<div aria-busy="true">
<span class="sr-only">Loading</span>
<div class="wu-skeleton text" aria-hidden="true"></div>
<div class="wu-skeleton text" aria-hidden="true"></div>
<div class="wu-skeleton text" aria-hidden="true"></div>
</div>
Loading
<div class="flex x-center gap-3" aria-busy="true">
<span class="sr-only">Loading</span>
<div class="wu-skeleton circle" aria-hidden="true"></div>
<div class="grow">
<div class="wu-skeleton text" aria-hidden="true" style="--wu-skeleton--Width: 40%"></div>
<div class="wu-skeleton text" aria-hidden="true"></div>
</div>
</div>
<div class="flex x-center gap-3" aria-hidden="true">
<div class="wu-skeleton" style="--wu-skeleton--Width: 8rem; --wu-skeleton--Height: 5rem"></div>
<div class="wu-skeleton circle" style="--wu-skeleton--Size: 4rem"></div>
</div>

The animated word adds a shimmer that sweeps across each shape. wu-animated on an ancestor turns it on for every skeleton inside. Siblings start one after another, as a wave. Motion runs only under prefers-reduced-motion: no-preference.

Loading
<div class="wu-animated" aria-busy="true">
<span class="sr-only">Loading</span>
<div class="wu-skeleton text" aria-hidden="true"></div>
<div class="wu-skeleton text" aria-hidden="true"></div>
<div class="wu-skeleton text" aria-hidden="true"></div>
</div>

The shimmer sweeps in the reading direction: from the right in right-to-left text. The shorter last line keeps to the inline start.

جارٍ التحميل
<div class="flex x-center gap-3 wu-animated" aria-busy="true">
<span class="sr-only">جارٍ التحميل</span>
<div class="wu-skeleton circle" aria-hidden="true"></div>
<div class="grow">
<div class="wu-skeleton text" aria-hidden="true"></div>
<div class="wu-skeleton text" aria-hidden="true"></div>
</div>
</div>
@use "@wovenui/components/skeleton";

The skeleton needs no other component.