Back to compare picker

Offline state vs Error state vs Loading spinner vs Progress bar

Use offline state when connectivity changes what can be read, edited, queued, or synced; use error state for confirmed failures, spinner for short indeterminate waits, and progress bar for measurable operations.

Learn the decision

Match the interaction to the person's task

Use offline state when connectivity changes what can be read, edited, queued, or synced; use error state for confirmed failures, spinner for short indeterminate waits, and progress bar for measurable operations.

Offline state

Use it when: Connection loss or server reachability changes the user's current task.

Make this state clear: Offline banner or local status that names affected scope.

Observe the result: A user loses connection while editing an inspection note, sees it saved on this device, attaches photos to a queue, and later watches the queue sync after reconnect.

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 →

Loading spinner

Use it when: The operation has defined resolution, timeout, cancellation, or failure paths.

Make this state clear: Inline processing state for a button or small local action.

Observe the result: After submit, users see payment PAY-2048 processing, can tell the button is temporarily unavailable, and then get either success or retry guidance.

Study the full pattern →

Progress bar

Use it when: A system operation has a measurable total or bounded progress value.

Make this state clear: Idle state before the operation starts.

Observe the result: A user uploads evidence.zip, sees progress move from 12% to 64%, cancels before commit, retries after a network error, and gets a completed receipt only after server processing succeeds.

Study the full pattern →

Practice the judgment: Imagine this situation: A disconnected form says Saved even though the answer exists only on the device and may conflict later. 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 Offline stateError stateLoading spinnerProgress bar
UI or UX UI + UX - Connectivity-mode and local-work continuity stateUI + UX - Recoverable failure surfaceUI + UX - Bounded indeterminate wait indicator for a named action or regionUI + UX - Measurable system-operation progress indicator
UI guidance Show offline status where it changes the current task, naming what remains available such as cached reports, local draft editing, queued saves, or read-only history.Render a persistent error region near the affected content with a specific failure heading, plain-language cause, preserved context, and recovery actions.Render a compact spinner only beside, inside, or over the affected action, component, or page region, and pair it with concise text that names what is loading or processing.Show a labeled bar with a track, filled value, and nearby helper text that reports the measurable unit such as percent, bytes, rows, files, records, or stages.
UX guidance Use offline state to preserve trust and task continuity when connection loss changes what users can read, edit, submit, sync, refresh, or share.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.Prevent duplicate or conflicting actions while the operation is in flight, but keep context, status, safe cancellation, and timeout recovery available when the wait exceeds the expected threshold.Use a progress bar when the system can honestly report movement toward a known finish and users need to decide whether to wait, cancel, retry, continue elsewhere, or return later.
Good UI A field report says Offline: 3 edits saved on this device, cached customer history shown from 10:42, Submit disabled until connection returns, and Retry connection.A failed save state keeps the draft visible and labels the support reference separately from the user-facing explanation.A Pay invoice button becomes Processing payment with a small spinner, disables only duplicate payment actions, and leaves the invoice reference visible.A document upload card says Uploading evidence.zip, shows 64%, 32 of 50 MB, a Cancel action, and keeps the rest of the form usable.
Bad UI A blank page says You are offline even though the app has cached drafts and help content.Tiny transient toast for a blocking failure.A search results panel shows skeleton rows, a spinner, and a progress bar for the same request.A progress bar reads 100% complete while virus scanning and server acceptance are still pending.
Good UX A user loses connection while editing an inspection note, sees it saved on this device, attaches photos to a queue, and later watches the queue sync after reconnect.User input and filter context are preserved after failure, and retry returns to recovered content or a clear still-failed state.After submit, users see payment PAY-2048 processing, can tell the button is temporarily unavailable, and then get either success or retry guidance.A user uploads evidence.zip, sees progress move from 12% to 64%, cancels before commit, retries after a network error, and gets a completed receipt only after server processing succeeds.
Bad UX A submitted offline form disappears from the screen even though it was neither queued nor accepted by the server.Clearing work after save failure.The spinner blocks the whole workspace for a small table refresh and prevents users from continuing other work.Users leave after 100% transfer even though server processing later rejects the file.
Best fit Connection loss or server reachability changes the user's current task.A system or task failure blocks expected content or action.The operation has defined resolution, timeout, cancellation, or failure paths.A system operation has a measurable total or bounded progress value.
Avoid when A single request failed while the rest of the app is reachable and an error state is clearer.Nothing exists yet and the state is expected.The content layout is predictable and a skeleton would better preserve structure.The wait is short and only needs scoped activity feedback.
Required state Offline banner or local status that names affected scope.Normal expected state before failure.Inline processing state for a button or small local action.Idle state before the operation starts.
Accessibility burden Announce significant connectivity changes with status messaging when they affect the current task.Use appropriate alert or status semantics for newly appearing critical errors.Give the spinner or affected region an accessible name that identifies the operation.Provide an accessible name that identifies the operation and affected object.
Common misuse Showing only a browser-style offline page when useful cached or local content exists.Using a transient toast for critical errors.Showing an unlabeled spinner on a blank page.Fabricating progress values just to make users feel movement.

Offline state

UI or UX
UI + UX - Connectivity-mode and local-work continuity state
UI guidance
Show offline status where it changes the current task, naming what remains available such as cached reports, local draft editing, queued saves, or read-only history.
UX guidance
Use offline state to preserve trust and task continuity when connection loss changes what users can read, edit, submit, sync, refresh, or share.
Good UI
A field report says Offline: 3 edits saved on this device, cached customer history shown from 10:42, Submit disabled until connection returns, and Retry connection.
Bad UI
A blank page says You are offline even though the app has cached drafts and help content.
Good UX
A user loses connection while editing an inspection note, sees it saved on this device, attaches photos to a queue, and later watches the queue sync after reconnect.
Bad UX
A submitted offline form disappears from the screen even though it was neither queued nor accepted by the server.
Best fit
Connection loss or server reachability changes the user's current task.
Avoid when
A single request failed while the rest of the app is reachable and an error state is clearer.
Required state
Offline banner or local status that names affected scope.
Accessibility burden
Announce significant connectivity changes with status messaging when they affect the current task.
Common misuse
Showing only a browser-style offline page when useful cached or local content exists.

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.

Loading spinner

UI or UX
UI + UX - Bounded indeterminate wait indicator for a named action or region
UI guidance
Render a compact spinner only beside, inside, or over the affected action, component, or page region, and pair it with concise text that names what is loading or processing.
UX guidance
Prevent duplicate or conflicting actions while the operation is in flight, but keep context, status, safe cancellation, and timeout recovery available when the wait exceeds the expected threshold.
Good UI
A Pay invoice button becomes Processing payment with a small spinner, disables only duplicate payment actions, and leaves the invoice reference visible.
Bad UI
A search results panel shows skeleton rows, a spinner, and a progress bar for the same request.
Good UX
After submit, users see payment PAY-2048 processing, can tell the button is temporarily unavailable, and then get either success or retry guidance.
Bad UX
The spinner blocks the whole workspace for a small table refresh and prevents users from continuing other work.
Best fit
The operation has defined resolution, timeout, cancellation, or failure paths.
Avoid when
The content layout is predictable and a skeleton would better preserve structure.
Required state
Inline processing state for a button or small local action.
Accessibility burden
Give the spinner or affected region an accessible name that identifies the operation.
Common misuse
Showing an unlabeled spinner on a blank page.

Progress bar

UI or UX
UI + UX - Measurable system-operation progress indicator
UI guidance
Show a labeled bar with a track, filled value, and nearby helper text that reports the measurable unit such as percent, bytes, rows, files, records, or stages.
UX guidance
Use a progress bar when the system can honestly report movement toward a known finish and users need to decide whether to wait, cancel, retry, continue elsewhere, or return later.
Good UI
A document upload card says Uploading evidence.zip, shows 64%, 32 of 50 MB, a Cancel action, and keeps the rest of the form usable.
Bad UI
A progress bar reads 100% complete while virus scanning and server acceptance are still pending.
Good UX
A user uploads evidence.zip, sees progress move from 12% to 64%, cancels before commit, retries after a network error, and gets a completed receipt only after server processing succeeds.
Bad UX
Users leave after 100% transfer even though server processing later rejects the file.
Best fit
A system operation has a measurable total or bounded progress value.
Avoid when
The wait is short and only needs scoped activity feedback.
Required state
Idle state before the operation starts.
Accessibility burden
Provide an accessible name that identifies the operation and affected object.
Common misuse
Fabricating progress values just to make users feel movement.
Decision rules
  • Choose offline state when the device or app cannot reach the network and users need to know which cached data, local edits, queued actions, and retry paths remain available.
  • Choose error state when a specific load, save, submit, permission, validation, sync, or computation attempt has failed and the affected object needs persistent recovery.
  • Choose loading spinner when a named action or region is actively working for a short indeterminate wait and has not yet resolved to offline, success, failure, or progress.
  • Choose progress bar when the system can report a meaningful numeric value for upload, download, import, export, validation, or processing work.
  • Do not replace an offline mode with a blank error page when cached content, local drafts, read-only history, or queued saves can still be useful.
  • Do not claim work is saved online while offline; label it as saved on this device, queued, waiting to sync, or sync failed.
  • Use offline state at the smallest honest scope: whole app, page, panel, record, action, or field, depending on what connectivity actually blocks.
  • When connection returns, transition from offline to syncing, synced, conflict, or failed state instead of silently hiding queued changes.
Inspect live examples
Failure modes
  • A disconnected form says Saved even though the answer exists only on the device and may conflict later.
  • The app shows a browser-style offline page even though the dashboard, drafts, and help articles were cached.
  • All controls are disabled because the network is gone, including safe read-only navigation and local editing.
  • A spinner runs forever during connection loss instead of switching to offline state with retry and cached data.
  • A progress bar pretends to upload while the request is queued locally with no network.
  • The app reconnects and clears the offline banner without syncing queued changes or surfacing conflicts.

Saved items