Back to compare picker

Loading skeleton vs Empty state vs Error state

Use loading skeletons while predictable content is still unresolved, empty states after the system confirms legitimate absence, and error states after expected content or progress fails.

Learn the decision

Match the interaction to the person's task

Use loading skeletons while predictable content is still unresolved, empty states after the system confirms legitimate absence, and error states after expected content or progress fails.

Loading skeleton

Use it when: The content shape is predictable.

Make this state clear: Initial skeleton placeholder state with region marked busy.

Observe the result: Users see that reports are pending, then can switch the demo to loaded, empty, or error outcomes on a bounded path.

Study the full pattern →

Empty state

Use it when: A next setup, creation, import, sample, or access-request action is available or explainable.

Make this state clear: First-use empty state before any objects exist.

Observe the result: Users can create the first project, import existing work, or request access depending on the actual cause.

Study the full pattern →

Error state

Use it when: A system or task failure blocks expected content or action.

Make this state clear: Normal expected state before failure.

Observe the result: User input and filter context are preserved after failure, and retry returns to recovered content or a clear still-failed state.

Study the full pattern →

Practice the judgment: Imagine this situation: Clickable placeholder rows receive focus before real content exists. Write the person's goal, choose one of these patterns, and show the state that helps the person continue. Use the decision rules and source trail below to explain your choice.

Review the underlying principle →

Decision dimensions

Dimension Loading skeletonEmpty stateError state
UI or UX UI + UX - Bounded content loading placeholderUI + UX - Resolved no-data content surfaceUI + UX - Recoverable failure surface
UI guidance Keep skeleton dimensions stable, mark the affected region busy, and use subtle or reduced-motion-respecting animation only while loading is unresolved.Keep surrounding context such as table title, filters, or workspace name visible so users know exactly what is empty.Render a persistent error region near the affected content with a specific failure heading, plain-language cause, preserved context, and recovery actions.
UX guidance Reduce uncertainty and layout shift while predictable content loads, then resolve clearly to real content, empty state, or error state.Move users toward the first useful object or prerequisite, and replace unavailable actions with permission or configuration guidance.Match the next action to the failure cause: retry transient failures, edit correctable input, use cached fallback for read-only continuity, or provide support reference when recovery is outside the UI.
Good UI The interface shows a clear action and state.Permission variant explains that projects exist only after an admin grants access and offers Request access instead of Create.A failed save state keeps the draft visible and labels the support reference separately from the user-facing explanation.
Bad UI Skeleton rows look like clickable report cards and receive focus before content exists.Oversized decorative art and vague welcome copy that hides the task.Tiny transient toast for a blocking failure.
Good UX Users see that reports are pending, then can switch the demo to loaded, empty, or error outcomes on a bounded path.Users can create the first project, import existing work, or request access depending on the actual cause.User input and filter context are preserved after failure, and retry returns to recovered content or a clear still-failed state.
Bad UX Large layout shift after content arrives.A primary Create button is shown to a read-only user and fails after activation.Clearing work after save failure.
Best fit The content shape is predictable.A next setup, creation, import, sample, or access-request action is available or explainable.A system or task failure blocks expected content or action.
Avoid when A specific progress indicator or blocking message is required.The absence was caused by filters or search.Nothing exists yet and the state is expected.
Required state Initial skeleton placeholder state with region marked busy.First-use empty state before any objects exist.Normal expected state before failure.
Accessibility burden Mark the loading region busy or provide concise status text.Keep the message in normal reading order near the empty region it explains.Use appropriate alert or status semantics for newly appearing critical errors.
Common misuse Showing skeletons forever.Using marketing copy instead of a task-specific next step.Using a transient toast for critical errors.

Loading skeleton

UI or UX
UI + UX - Bounded content loading placeholder
UI guidance
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.
Good UI
The interface shows a clear action and state.
Bad UI
Skeleton rows look like clickable report cards and receive focus before content exists.
Good UX
Users see that reports are pending, then can switch the demo to loaded, empty, or error outcomes on a bounded path.
Bad UX
Large layout shift after content arrives.
Best fit
The content shape is predictable.
Avoid when
A specific progress indicator or blocking message is required.
Required state
Initial skeleton placeholder state with region marked busy.
Accessibility burden
Mark the loading region busy or provide concise status text.
Common misuse
Showing skeletons forever.

Empty state

UI or UX
UI + UX - Resolved no-data content surface
UI guidance
Keep surrounding context such as table title, filters, or workspace name visible so users know exactly what is empty.
UX guidance
Move users toward the first useful object or prerequisite, and replace unavailable actions with permission or configuration guidance.
Good UI
Permission variant explains that projects exist only after an admin grants access and offers Request access instead of Create.
Bad UI
Oversized decorative art and vague welcome copy that hides the task.
Good UX
Users can create the first project, import existing work, or request access depending on the actual cause.
Bad UX
A primary Create button is shown to a read-only user and fails after activation.
Best fit
A next setup, creation, import, sample, or access-request action is available or explainable.
Avoid when
The absence was caused by filters or search.
Required state
First-use empty state before any objects exist.
Accessibility burden
Keep the message in normal reading order near the empty region it explains.
Common misuse
Using marketing copy instead of a task-specific next step.

Error state

UI or UX
UI + UX - Recoverable failure surface
UI guidance
Render a persistent error region near the affected content with a specific failure heading, plain-language cause, preserved context, and recovery actions.
UX guidance
Match the next action to the failure cause: retry transient failures, edit correctable input, use cached fallback for read-only continuity, or provide support reference when recovery is outside the UI.
Good UI
A failed save state keeps the draft visible and labels the support reference separately from the user-facing explanation.
Bad UI
Tiny transient toast for a blocking failure.
Good UX
User input and filter context are preserved after failure, and retry returns to recovered content or a clear still-failed state.
Bad UX
Clearing work after save failure.
Best fit
A system or task failure blocks expected content or action.
Avoid when
Nothing exists yet and the state is expected.
Required state
Normal expected state before failure.
Accessibility burden
Use appropriate alert or status semantics for newly appearing critical errors.
Common misuse
Using a transient toast for critical errors.
Decision rules
  • Prefer loading skeleton when asynchronous content is pending and the final layout shape is predictable enough to reserve stable space.
  • Prefer empty state after loading resolves successfully but the collection or surface legitimately has no content.
  • Prefer error state after loading, saving, syncing, or computation fails and users need retry, fallback, or escalation.
  • Do not use skeletons for unknown layouts, long-running jobs with meaningful progress, or blocking operations that need a percent, step count, or explicit wait message.
  • Do not leave skeletons visible indefinitely; every skeleton needs a bounded transition to loaded, empty, error, or cancelled state.
  • Do not make skeleton placeholders focusable or clickable; they represent pending structure, not disabled content.
  • If content shape changes dramatically after load, redesign the skeleton or use a simpler loading indicator so the placeholder does not create layout shift or false expectations.
Inspect live examples
Failure modes
  • Skeleton screen never resolves and masks a real failure.
  • Clickable placeholder rows receive focus before real content exists.
  • Loaded content shifts into a different layout from the placeholder.
  • Skeleton is shown after filters return zero results instead of no-results or empty state.
  • Skeleton and spinner appear together and compete as progress signals.
  • Shimmer animation ignores reduced-motion preferences.

Saved items