Feedback Skeleton

Skeleton

Pure-CSS loading placeholders. Drop-in shape primitives that pulse (or wave) while content loads. No JavaScript required — compose shapes with layout helpers to mirror any real UI.

Shape Primitives

Every shape is wf-skel plus one modifier. Use them as building blocks for any content skeleton.

All Shapes

Heading, text lines, badge, button, circle, thumbnail, and a small rectangle — the full primitive set.

HTML
<!-- Heading -->
<div class="wf-skel wf-skel-heading"></div>

<!-- Text lines with width overrides -->
<div class="wf-skel wf-skel-text"></div>
<div class="wf-skel wf-skel-text wf-skel-w-75"></div>
<div class="wf-skel wf-skel-text wf-skel-w-50"></div>

<!-- Inline elements -->
<div class="wf-skel wf-skel-badge"></div>
<div class="wf-skel wf-skel-btn"></div>

<!-- Circle and thumbnail -->
<div class="wf-skel wf-skel-circle"></div>
<div class="wf-skel wf-skel-thumb"></div>

<!-- Small rectangle -->
<div class="wf-skel wf-skel-rect wf-skel-rect-sm"></div>

Circle Sizes

Six sizes for avatar and icon placeholders. Sizes from 1.5 rem (xs) to 7 rem (2xl).

xs
sm
default
lg
xl
2xl
HTML
<div class="wf-skel wf-skel-circle wf-skel-circle-xs"></div>
<div class="wf-skel wf-skel-circle wf-skel-circle-sm"></div>
<div class="wf-skel wf-skel-circle"></div>
<div class="wf-skel wf-skel-circle wf-skel-circle-lg"></div>
<div class="wf-skel wf-skel-circle wf-skel-circle-xl"></div>
<div class="wf-skel wf-skel-circle wf-skel-circle-2xl"></div>

Rectangles & Aspect Ratios

Fixed-height variants for banners and thumbnails; aspect-ratio variants for responsive media skeletons.

Fixed Height

rect-sm (6 rem), default (12 rem), rect-lg (18 rem).

HTML
<div class="wf-skel wf-skel-rect wf-skel-rect-sm"></div>
<div class="wf-skel wf-skel-rect"></div>
<div class="wf-skel wf-skel-rect wf-skel-rect-lg"></div>

Aspect Ratios

Height is automatic — the skeleton scales with container width.

HTML
<!-- 16/9 video -->
<div class="wf-skel wf-skel-rect wf-skel-rect-video"></div>

<!-- 21/9 wide -->
<div class="wf-skel wf-skel-rect wf-skel-rect-wide"></div>

<!-- 1/1 square -->
<div class="wf-skel wf-skel-rect wf-skel-rect-square"></div>

<!-- 3/4 portrait -->
<div class="wf-skel wf-skel-rect wf-skel-rect-portrait"></div>

Width Utilities

Vary text-line lengths to simulate natural paragraph rhythm. Add any wf-skel-w-* class alongside a shape class.

25% – 100%

Nine steps: 25, 33, 40, 50, 60, 66, 75, 80, and full (100%).

HTML
<div class="wf-skel wf-skel-text wf-skel-w-full"></div>
<div class="wf-skel wf-skel-text wf-skel-w-80"></div>
<div class="wf-skel wf-skel-text wf-skel-w-75"></div>
<div class="wf-skel wf-skel-text wf-skel-w-66"></div>
<div class="wf-skel wf-skel-text wf-skel-w-60"></div>
<div class="wf-skel wf-skel-text wf-skel-w-50"></div>
<div class="wf-skel wf-skel-text wf-skel-w-40"></div>
<div class="wf-skel wf-skel-text wf-skel-w-33"></div>
<div class="wf-skel wf-skel-text wf-skel-w-25"></div>

Animation

Two styles: the default pulse fades opacity, and wave sweeps a highlight across. Both support speed overrides.

Pulse (default)

Applied automatically. No extra class needed.

HTML
<!-- Default pulse — no extra class needed -->
<div class="wf-skel-group">
  <div class="wf-skel wf-skel-heading wf-skel-w-60"></div>
  <div class="wf-skel wf-skel-text"></div>
  <div class="wf-skel wf-skel-text wf-skel-w-75"></div>
</div>

Wave

Add wf-skel--wave to a single element, or wf-skel-group--wave on a container to wave all children.

HTML
<!-- Single element wave -->
<div class="wf-skel wf-skel-rect wf-skel--wave"></div>

<!-- Group wave (all children) -->
<div class="wf-skel-group wf-skel-group--wave">
  <div class="wf-skel wf-skel-heading wf-skel-w-60"></div>
  <div class="wf-skel wf-skel-text"></div>
  <div class="wf-skel wf-skel-text wf-skel-w-75"></div>
</div>

Speed wf-skel-speed-slow / -fast

Override the animation duration. Slow: 2.5 s — Default: 1.5 s — Fast: 0.8 s.

Slow (2.5 s)
Default (1.5 s)
Fast (0.8 s)
HTML
<div class="wf-skel wf-skel-text wf-skel-speed-slow"></div>
<div class="wf-skel wf-skel-text"></div>
<div class="wf-skel wf-skel-text wf-skel-speed-fast"></div>

Layout Helpers

Three utilities for assembling composite skeletons without writing extra CSS.

Group wf-skel-group

Stacks children in a column with consistent gap — the default wrapper for a block of text lines.

HTML
<div class="wf-skel-group">
  <div class="wf-skel wf-skel-heading wf-skel-w-50"></div>
  <div class="wf-skel wf-skel-text"></div>
  <div class="wf-skel wf-skel-text wf-skel-w-80"></div>
  <div class="wf-skel wf-skel-text wf-skel-w-60"></div>
</div>

Row & Row Fill wf-skel-row / -row-fill

wf-skel-row aligns a circle or thumbnail with text side-by-side. wf-skel-row-fill fills the remaining width.

HTML
<div class="wf-skel-row">
  <div class="wf-skel wf-skel-circle"></div>
  <div class="wf-skel-row-fill">
    <div class="wf-skel wf-skel-text wf-skel-w-60"></div>
    <div class="wf-skel wf-skel-text wf-skel-w-40"></div>
  </div>
</div>

<!-- With thumbnail -->
<div class="wf-skel-row">
  <div class="wf-skel wf-skel-thumb"></div>
  <div class="wf-skel-row-fill">
    <div class="wf-skel wf-skel-text wf-skel-w-66"></div>
    <div class="wf-skel wf-skel-text wf-skel-w-40"></div>
  </div>
</div>

Composite Examples

Full skeleton screens built from primitives and layout helpers. Mirror your real UI structure as closely as possible for the least layout shift when content arrives.

Card Skeleton

Image header + text body + action footer.

HTML
<div class="card">
  <div class="wf-skel wf-skel-rect wf-skel-rect-video"></div>
  <div class="card-body">
    <div class="wf-skel-group">
      <div class="wf-skel wf-skel-heading wf-skel-w-75"></div>
      <div class="wf-skel wf-skel-text"></div>
      <div class="wf-skel wf-skel-text wf-skel-w-80"></div>
      <div class="wf-skel wf-skel-text wf-skel-w-60"></div>
      <div class="wf-skel wf-skel-btn"></div>
    </div>
  </div>
</div>

List Skeleton

Wave animation applied at group level — all rows animate in sync.

HTML
<div class="wf-skel-group wf-skel-group--wave">
  <div class="wf-skel-row">
    <div class="wf-skel wf-skel-circle"></div>
    <div class="wf-skel-row-fill">
      <div class="wf-skel wf-skel-text wf-skel-w-66"></div>
      <div class="wf-skel wf-skel-text wf-skel-w-40"></div>
    </div>
  </div>
  <!-- repeat rows … -->
</div>

Profile Skeleton

Centred avatar with name, bio, badges, and action buttons.

HTML
<div class="profile-card">
  <div class="wf-skel wf-skel-circle wf-skel-circle-2xl"></div>
  <div class="wf-skel-group">
    <div class="wf-skel wf-skel-heading wf-skel-w-50"></div>
    <div class="wf-skel wf-skel-text wf-skel-w-66"></div>
    <div class="wf-skel wf-skel-badge"></div>
  </div>
  <div class="wf-skel wf-skel-btn"></div>
</div>

Media Post Skeleton

Author row → media → caption — a typical social or news feed entry.

HTML
<!-- Author row -->
<div class="wf-skel-row">
  <div class="wf-skel wf-skel-circle wf-skel-circle-sm"></div>
  <div class="wf-skel-row-fill">
    <div class="wf-skel wf-skel-text wf-skel-w-40"></div>
    <div class="wf-skel wf-skel-text wf-skel-w-25"></div>
  </div>
  <div class="wf-skel wf-skel-badge"></div>
</div>

<!-- Media -->
<div class="wf-skel wf-skel-rect wf-skel-rect-video"></div>

<!-- Caption -->
<div class="wf-skel-group">
  <div class="wf-skel wf-skel-text"></div>
  <div class="wf-skel wf-skel-text wf-skel-w-75"></div>
</div>

Accessibility

Skeleton screens are decorative. Use wf-skel-sr-only to provide a screen-reader label so assistive technology announces loading context instead of reading each empty block.

Screen Reader Label wf-skel-sr-only

Wrap the skeleton in a role="status" element and add a visually hidden description.

Loading article…
HTML
<div role="status" aria-label="Loading article">
  <span class="wf-skel-sr-only">Loading article…</span>

  <div class="wf-skel-group">
    <div class="wf-skel wf-skel-heading wf-skel-w-75"></div>
    <div class="wf-skel wf-skel-text"></div>
    <div class="wf-skel wf-skel-text wf-skel-w-80"></div>
  </div>
</div>

Custom Properties

Property Default Description
--wf-skel-color color-mix(border 75%, surface) Fill color of every skeleton block. Override on a container to theme an entire skeleton screen.
--wf-skel-speed 1.5s Animation cycle duration. Also changed by wf-skel-speed-slow (2.5 s) and wf-skel-speed-fast (0.8 s).
--wf-skel-radius var(--wf-radius-2, .375rem) Border radius for block shapes. Text and heading use a fixed pill radius and are not affected.

Theme Override

Set properties on a container to retheme an entire skeleton screen without touching individual elements.

HTML
<!-- Override color and speed on a parent -->
<div style="--wf-skel-color: color-mix(in srgb, var(--wf-info) 20%, transparent);
            --wf-skel-speed: 2s;">
  <div class="wf-skel-group">
    <div class="wf-skel wf-skel-heading wf-skel-w-60"></div>
    <div class="wf-skel wf-skel-text"></div>
    <div class="wf-skel wf-skel-text wf-skel-w-75"></div>
  </div>
</div>

Class Reference

All modifier classes available on .wf-skel

Class Type Description
wf-skel Base Base skeleton block. Pulses by default. All shape classes extend this.
wf-skel-text Shape Single line of body text height (0.75 rem), full width, pill radius.
wf-skel-heading Shape Heading-height block (1.125 rem), full width, pill radius.
wf-skel-btn Shape Button-sized block (6 rem × 2.25 rem).
wf-skel-badge Shape Inline badge pill (4 rem × 1.25 rem).
wf-skel-circle / -circle-xs / -sm / -lg / -xl / -2xl Shape Circle avatar. Default 2.5 rem; sizes: xs (1.5), sm (2), lg (3.5), xl (5), 2xl (7 rem).
wf-skel-rect / -rect-sm / -rect-lg / -rect-video / -rect-square / -rect-wide / -rect-portrait Shape Rectangle block. Default 12 rem; sm (6 rem), lg (18 rem); aspect-ratio variants: video (16/9), square (1/1), wide (21/9), portrait (3/4).
wf-skel-thumb Shape Thumbnail square (4 rem × 4 rem, rounded), flex-shrink: 0.
wf-skel-w-25 / -33 / -40 / -50 / -60 / -66 / -75 / -80 / -full Width Override element width. Combine with wf-skel-text to simulate varying line lengths.
wf-skel--wave Animation Replace pulse with a sweeping wave on a single element.
wf-skel-group--wave Animation Apply wave animation to every wf-skel inside this container.
wf-skel-speed-slow / -fast Animation Override animation duration: slow (2.5 s), fast (0.8 s). Default is 1.5 s.
wf-skel-group Layout Flex column container with 0.625 rem gap. Wraps stacked skeleton lines.
wf-skel-row Layout Flex row with 0.75 rem gap, vertically centred. Use to pair a circle with text lines.
wf-skel-row-fill Layout Flex column child that grows to fill remaining row space. Place inside wf-skel-row .
wf-skel-sr-only a11y Visually hidden label. Add a descriptive string inside a skeleton wrapper for screen-reader context.
Show More