Back to compare picker

Loading skeleton vs Empty state vs Error state

Prefer loading skeleton when asynchronous content is pending and the final layout shape is predictable enough to reserve stable space.

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 Render neutral skeleton blocks that reserve the final content structure without fake readable text, fake controls, or focusable placeholder elements.Render a resolved no-data region with a specific heading, cause text, one primary action when available, optional secondary path, and restrained illustration or icon support.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.Help users distinguish legitimate absence from loading, no-results, error, permission, and setup conditions before offering a next step.Help users recover when expected loading, saving, validation, sync, permission, or computation fails without losing their work.
Good UI Three report-card placeholders match the final card heights and are replaced by real cards without shifting the panel.No projects yet heading, short explanation, Create project primary button, Import CSV secondary button, and visible workspace context.Reports could not load appears in the report section with the saved filter, Retry, Use cached data, and Contact support actions.
Bad UI Skeleton rows look like clickable report cards and receive focus before content exists.A blank white table body with no text, object name, or action.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 Skeleton never resolves.The same empty message appears for loading, search no-results, permission denial, and service failure.Clearing work after save failure.
Best fit The content shape is predictable.The product area can legitimately contain no user data.A system or task failure blocks expected content or action.
Avoid when The system cannot predict the content layout.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.Showing a blank page with no explanation.Using a transient toast for critical errors.

Loading skeleton

UI or UX
UI + UX - Bounded content loading placeholder
UI guidance
Render neutral skeleton blocks that reserve the final content structure without fake readable text, fake controls, or focusable placeholder elements.
UX guidance
Reduce uncertainty and layout shift while predictable content loads, then resolve clearly to real content, empty state, or error state.
Good UI
Three report-card placeholders match the final card heights and are replaced by real cards without shifting the panel.
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
Skeleton never resolves.
Best fit
The content shape is predictable.
Avoid when
The system cannot predict the content layout.
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
Render a resolved no-data region with a specific heading, cause text, one primary action when available, optional secondary path, and restrained illustration or icon support.
UX guidance
Help users distinguish legitimate absence from loading, no-results, error, permission, and setup conditions before offering a next step.
Good UI
No projects yet heading, short explanation, Create project primary button, Import CSV secondary button, and visible workspace context.
Bad UI
A blank white table body with no text, object name, or action.
Good UX
Users can create the first project, import existing work, or request access depending on the actual cause.
Bad UX
The same empty message appears for loading, search no-results, permission denial, and service failure.
Best fit
The product area can legitimately contain no user data.
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
Showing a blank page with no explanation.

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
Help users recover when expected loading, saving, validation, sync, permission, or computation fails without losing their work.
Good UI
Reports could not load appears in the report section with the saved filter, Retry, Use cached data, and Contact support actions.
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.