Spinner
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
When to use
Section titled “When to use”- 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.
When not to use
Section titled “When not to use”- 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.