Application · lesson 7 of 30 · Feedback, Status, And System State

Loading skeleton

Underlying principle: Status connects an action to a real system event. A useful message names the current state, its consequence, and the next available action.

Reserve the approximate final content structure with neutral non-interactive placeholders, mark the region busy, then replace the skeleton with loaded content, empty state, or error state on a bounded path.

Start with the decision

Does this fit your task?

The content shape is predictable.

Review the boundary: Compare the task with the alternatives in the decision section.

Review the decision →
Study the interaction

Follow the task before choosing the component

Status connects an action to a real system event. A useful message names the current state, its consequence, and the next available action.

01 / Recognize the need

What the person is doing

Content loads asynchronously and has a predictable final shape such as cards, rows, profile blocks, charts, or media tiles.

02 / Design the response

What the interface must communicate

Reserve the approximate final content structure with neutral non-interactive placeholders, mark the region busy, then replace the skeleton with loaded content, empty state, or error state on a bounded path.

Initial skeleton placeholder state with region marked busy.

03 / Judge the outcome

What to look for

What exact state replaces the skeleton if loading succeeds, returns empty, fails, or times out?

The placeholder geometry approximates the loaded content closely enough to reduce layout shift.

Decision first

Choose this pattern when the problem matches

Use when

  • The content shape is predictable.
  • Loading is short or bounded enough that the placeholder meaning remains clear.
  • Users benefit from knowing where asynchronous content will appear.

Avoid when

  • A specific progress indicator or blocking message is required.
  • The operation is long-running and users need job progress, queue position, or cancellation.
  • The result is already known to be empty, failed, or filtered out.
  • The placeholder would look like a disabled control users try to interact with.

Problem it prevents

Content loads asynchronously and has a predictable final shape such as cards, rows, profile blocks, charts, or media tiles.

Test the behavior

Try strong and weak versions of the interaction

Open the working example, try its controls, and compare the behavior against the decision guidance.

In the lab you can
  • switch between strong UI, weak UI, strong UX, and weak UX;
  • trigger required, empty, loading, error, and recovery states;
  • inspect keyboard and accessibility expectations beside the demo.
Launch Loading skeleton in the lab
Pattern anatomy

What a strong implementation has to make clear

User need

Content loads asynchronously and has a predictable final shape such as cards, rows, profile blocks, charts, or media tiles.

Pattern promise

Reserve the approximate final content structure with neutral non-interactive placeholders, mark the region busy, then replace the skeleton with loaded content, empty state, or error state on a bounded path.

Required state

Initial skeleton placeholder state with region marked busy.

Failure to inspect

Large layout shift after content arrives.

Access contract

Mark the loading region busy or provide concise status text.

Quality bar

The difference between expert and weak execution

Strong implementation

Specific, visible, recoverable

  • Users see that reports are pending, then can switch the demo to loaded, empty, or error outcomes on a bounded path.
  • If loading fails, the UI moves to a persistent error state instead of continuing shimmer forever.
Weak implementation

Vague, hidden, hard to recover from

  • Skeleton rows look like clickable report cards and receive focus before content exists.
  • A spinner and skeleton compete for the same region while the final content appears in a different layout.
  • Large layout shift after content arrives.
  • Animated shimmer that ignores reduced motion.
UI guidance
  • Render neutral skeleton blocks that reserve the final content structure without fake readable text, fake controls, or focusable placeholder elements.
  • Keep skeleton dimensions stable, mark the affected region busy, and use subtle or reduced-motion-respecting animation only while loading is unresolved.
UX guidance
  • Reduce uncertainty and layout shift while predictable content loads, then resolve clearly to real content, empty state, or error state.
  • Use skeletons for short bounded waits and switch to explicit progress, cancellation, or error recovery when the wait becomes long or fails.
Implementation contract

What the implementation must handle

States

  • Initial skeleton placeholder state with region marked busy.
  • Reduced-motion state for animated skeletons.
  • Refresh or partial-loading state where existing content remains trustworthy while only new areas are busy.

Interaction

  • The placeholder geometry approximates the loaded content closely enough to reduce layout shift.
  • Existing user focus remains stable while new content loads unless focus movement is required after completion.
  • When loaded content arrives, busy state is removed and real controls become available.

Accessibility

  • Mark the loading region busy or provide concise status text.
  • Avoid announcing every skeleton row as content.
  • Respect reduced-motion preferences for shimmer or pulse animation.
  • Remove busy state when the region resolves to loaded, empty, or error.

Review

  • What exact state replaces the skeleton if loading succeeds, returns empty, fails, or times out?
  • Can keyboard and screen reader users avoid interacting with placeholder-only content?
Evidence trail

Source-backed claims behind this guidance

Carbon Design System Loading

IBM Carbon Design System - checked

Carbon distinguishes loading indicators and skeleton states, recommending skeleton states for progressively displayed content.

SAP Fiori Skeleton Loading

SAP Fiori - checked

SAP Fiori documents skeleton loading as a screen loading progress indicator and warns against mixed progress indicators.

Nord Design System Skeleton

Nord Design System - checked

Nord documents dynamic-content skeletons, aria-busy regions, and removing busy state after load.

Cedar Design System Skeleton

REI Co-op Cedar Design System - checked

Cedar documents skeletons for regions, not specific interactive elements, and reduced-motion behavior.

Full agent/debug reference

Problem Context

  • Content loads asynchronously and has a predictable final shape such as cards, rows, profile blocks, charts, or media tiles.
  • A blank screen or centered spinner would not show where content will appear or would allow avoidable layout shift.
  • The system can distinguish loading from loaded, empty, failed, and timed-out states.

Selection Rules

  • Choose skeletons when the final content layout is known enough to reserve stable space.
  • Use skeletons for dynamic content regions rather than standalone buttons, inputs, or controls.
  • Keep skeletons neutral and abstract so they do not look like real text, fake data, or tappable controls.
  • Mark the loading region busy or provide a concise status so assistive technology does not treat placeholders as content.
  • Transition to loaded content, empty state, error state, or cancelled state on a bounded timeline.
  • Respect reduced-motion preferences when using shimmer or pulse animation.
  • Use progress bars, inline loading, or explicit job status instead when progress is measurable or the task blocks action.

Required States

  • Initial skeleton placeholder state with region marked busy.
  • Loaded state where real content replaces placeholders without layout jump.
  • Resolved empty state after successful loading returns no content.
  • Failure or timeout state after loading cannot complete.
  • Reduced-motion state for animated skeletons.
  • Refresh or partial-loading state where existing content remains trustworthy while only new areas are busy.

Interaction Contract

  • Skeleton placeholders are not focusable, clickable, selectable, or announced as real content.
  • The placeholder geometry approximates the loaded content closely enough to reduce layout shift.
  • The loading region communicates pending status without announcing every placeholder row.
  • Loading cannot continue indefinitely without switching to error, timeout, or support messaging.
  • Existing user focus remains stable while new content loads unless focus movement is required after completion.
  • When loaded content arrives, busy state is removed and real controls become available.

Implementation Checklist

  • Reserve stable dimensions for every skeleton region.
  • Match skeleton row, card, media, and text proportions to the final content density.
  • Avoid fake readable text and fake interactive controls.
  • Use aria-busy or equivalent status for the affected region.
  • Remove busy state when content, empty, or error state resolves.
  • Add timeout or failure handling so skeletons do not run forever.
  • Honor prefers-reduced-motion when animating shimmer or pulse.
  • Do not combine skeletons with competing spinners unless each indicator applies to a clearly different region.

Common Generated-UI Mistakes

  • Showing skeletons forever.
  • Using skeletons for unknown layout shapes.
  • Making placeholders look like tappable content.
  • Showing skeleton after a no-results or empty response is already known.
  • Leaving shimmer animation on for reduced-motion users.
  • Loading into a layout that has little relationship to the placeholder.

Critique Questions

  • Does this placeholder communicate pending structure without pretending content exists?
  • What exact state replaces the skeleton if loading succeeds, returns empty, fails, or times out?
  • Can keyboard and screen reader users avoid interacting with placeholder-only content?
Accessibility
  • Mark the loading region busy or provide concise status text.
  • Avoid announcing every skeleton row as content.
  • Do not place keyboard focus inside placeholder-only controls.
  • Respect reduced-motion preferences for shimmer or pulse animation.
  • Remove busy state when the region resolves to loaded, empty, or error.
Keyboard Behavior
  • Do not place keyboard focus inside placeholder-only controls.
  • Keep existing focus stable while content loads.
  • Make real controls focusable only after data resolves.
  • If loading fails, focus should remain near or move predictably to the persistent error state.
Variants
  • Card skeleton
  • Table row skeleton
  • Text skeleton
  • Media skeleton
  • Chart skeleton
  • Partial-region skeleton
  • Reduced-motion static skeleton

Verification

Source trail checked:

Saved items