Skip to content

Spinner

Edit on GitHub

An animated, indeterminate loading indicator that shows something is in progress, without conveying how much progress has been made or how long it will take.

@volvo-cars/css v2.5.1
  • Use a spinner for short, indeterminate waits (roughly 1–10 seconds) when you can’t predict completion time and content structure isn’t the point, for example authentication, connecting to a server, or verifying details.
  • Use a spinner for inline or button loading states that confirm an action was registered and prevent duplicate clicks, for example turning “Save” or “Pay now” into a spinner mid-request.
  • Use a spinner for section-level loading, where only part of the interface updates and the rest stays usable, for example a dashboard widget refreshing while the rest of the page stays interactive.
  • Use a full-screen spinner for critical operations that must complete before the user can continue, for example app startup, payment processing, or secure verification.
  • Pair a spinner with contextual text for sensitive or high-stakes actions (“Processing payment”, “Verifying details”) to reduce anxiety. Context matters more than the spinner itself here.
  • Use a spinner when content structure is too variable or unpredictable to represent with a skeleton.
  • Use a spinner when implementation budget is low. It’s the simplest loading indicator to add and requires no placeholder design.
  • Don’t show a spinner for loads under 1 second. A spinner that flashes for a split second disrupts the experience more than a brief blank state. Add a delay before showing it.
  • Don’t use a bare spinner for long or unpredictable waits (10 seconds or more). Without a progress signal, users assume the app is frozen and repeat taps, refresh, or submit again.
  • Don’t use a spinner for known, structured layouts, such as feeds, dashboards, search results, or tables. A spinner discards layout information the interface already knows, and replaces a progressive reveal with everything popping in at once.
  • Don’t use a spinner for determinate, measurable progress, such as uploads, downloads, installs, or multi-step processes. A spinner can’t communicate “80% done” and increases uncertainty instead of reducing it.
  • Don’t use a spinner for full-page reloads triggered by navigation. It breaks continuity and feels heavier than necessary.
  • Don’t use a spinner for repeated or frequent polling updates. It causes flicker and distracts from content that’s mostly already there.
  • Don’t use a spinner for background or non-blocking operations. Don’t interrupt the user’s flow with a blocking indicator.

Choose a size that fits the surrounding control or loading region.