What Is a Loading Spinner?
A loading spinner is a small animated indicator, usually a rotating circle or set of dots, that tells users a page or action is still working and has not frozen. It reassures people during a wait by signalling progress is happening, even when the exact finish time is unknown. Spinners are common while data loads, a form submits, or an image processes. Used briefly they calm anxiety, but a spinner that lingers for many seconds stops reassuring and instead flags a slow, poorly optimized site that needs attention.
- What it is
- An animated indeterminate indicator showing that work is in progress
- Best for
- Short, unpredictable waits under a few seconds
- Perceived-wait rule
- Show feedback for actions over ~1 second so users know the system responded (Nielsen Norman Group)
- Accessibility
- Announce status with an ARIA live region or role of status so screen readers hear it (WAI-ARIA)
- Better alternative
- Skeleton screens or progress bars often feel faster than a bare spinner (web.dev)
What a loading spinner actually is #
A loading spinner is an animated visual, most often a spinning circle, arc, or pulsing dots, that signals a page or process is busy and has not stalled. It is an indeterminate indicator, meaning it shows that something is happening without saying how long it will take or how much is left. That distinguishes it from a progress bar, which fills up toward a known end. Spinners appear during the small gaps when a site fetches data, submits a form, or waits on a server response. Their whole job is psychological: a moving element reassures the visitor that the click registered and the machine is working, preventing the frustration of a screen that looks frozen. Designers reach for spinners because they are simple, familiar, and require no knowledge of the exact wait time. Getting these micro-interactions right is part of the interface craft covered on our /services/ui-ux-design page, where small feedback signals shape how responsive a product feels.
When a spinner reassures users #
A spinner works best for short, unpredictable waits, the moments between about one and a few seconds where the system needs a beat to respond. Research on interface responsiveness suggests that any action taking longer than roughly a second should show feedback, or users start to wonder whether their click did anything (Nielsen Norman Group). In that window a spinner is ideal: it acknowledges the input instantly and covers a delay too short and too variable to justify a progress bar. Good places include submitting a login, loading a dashboard panel, or fetching search results. The spinner appears the instant the user acts, so there is no dead gap where the interface seems ignored. This kind of immediate acknowledgement is central to how an application feels trustworthy, and it is a detail we build into every interactive feature on our /services/web-app-development page, so users never stare at an unresponsive screen wondering what went wrong.
When a spinner signals a slow site #
The same spinner that reassures for two seconds becomes a warning sign at ten. When a spinner keeps turning well past a few seconds, it stops meaning working and starts meaning stuck, and users grow anxious, reload the page, or abandon it entirely. A long-running spinner is often a symptom, not a solution: it papers over a genuinely slow page rather than fixing the underlying delay. If your spinner routinely spins for many seconds, the real problem is performance, oversized images, bloated scripts, slow database queries, or a sluggish host. Google measures actual load experience through Core Web Vitals, and a spinner does nothing to improve those scores. The right response is to make the page fast rather than to decorate the wait, which is exactly what our /services/speed-optimization page addresses. You can also check how your pages score today with the free /tools/website-grader before deciding whether a spinner is masking a deeper issue.
How a spinner is built in code #
At its simplest a loading spinner is a styled element with a CSS animation that rotates it continuously, plus an accessible label so assistive technology announces the busy state. No JavaScript library is required for the visual itself, since a rotating border and a keyframe animation do the work. The important details are the accessibility markup and motion sensitivity: give the spinner a role of status and include visually hidden text so screen readers announce that content is loading, and honour the prefers-reduced-motion setting by slowing the animation for users who find fast spinning uncomfortable. The example below is minimal and dependency-free, showing the animation, the hidden label, and the reduced-motion override together so the spinner is both visible to sighted users and announced to everyone else.
<div class="spinner" role="status" aria-live="polite">
<span class="visually-hidden">Loading…</span>
</div>
<style>
.spinner {
width: 2rem; height: 2rem;
border: 3px solid #ccc;
border-top-color: #333;
border-radius: 50%;
animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.visually-hidden {
position: absolute; width: 1px; height: 1px;
overflow: hidden; clip: rect(0 0 0 0);
}
@media (prefers-reduced-motion: reduce) {
.spinner { animation-duration: 2s; }
}
</style>Making spinners accessible #
A spinner that only communicates through motion excludes people who cannot see it, so accessibility has to be built in, not bolted on. Wrap the spinner in an element with a role of status or an ARIA live region set to polite, and include visually hidden text such as Loading so screen readers announce that content is on the way (WAI-ARIA). Without that, a blind user hears silence and has no idea the page is working. Respect the prefers-reduced-motion setting too, since fast, continuous spinning can trigger discomfort or nausea for people with vestibular conditions; slow or simplify the animation when that preference is on. Ensure the spinner has enough contrast against its background to be visible to low-vision users. When the wait ends, move focus or announce completion so keyboard and screen-reader users know the result arrived. These practices align with WCAG 2.2 and are part of the inclusive work covered on our /services/ada-compliance page.
Spinners versus skeleton screens and progress bars #
A spinner is only one way to fill a wait, and it is often not the best. A skeleton screen shows a grey placeholder shaped like the content that is coming, so the page feels like it is already assembling; users frequently perceive this as faster than a bare spinner because they see structure rather than a stalled circle (web.dev). A progress bar suits waits with a known length, such as a file upload, because it tells people exactly how much remains and roughly when it will end. A spinner fits the remaining case: short, indeterminate waits where you cannot show real progress and a placeholder would be overkill. Choosing the right pattern for each situation, rather than defaulting to a spinner everywhere, measurably affects how patient users feel and how many complete the task. Matching feedback to context is a core part of the improvements we make on our /services/conversion-optimization page, where reducing perceived friction lifts completion rates.
Common mistakes with loading spinners #
Several recurring errors turn a helpful spinner into a liability. The most damaging is using one to hide a genuinely slow page instead of fixing the speed, so users wait far longer than they should. Another is showing a spinner for waits so brief that it flickers on and off, which feels jittery; a tiny delay before showing it, or no spinner at all, is smoother. Some sites block the entire screen with a full-page spinner for a change that only affected one small area, freezing everything unnecessarily. Others forget the accessible label, leaving screen-reader users with no clue anything is loading, or ignore prefers-reduced-motion and spin aggressively at people who find it uncomfortable. A spinner that never resolves because an error was swallowed silently is the worst case, stranding the user forever. Auditing these details across a live site is the kind of practical review we deliver, and you can start free at /free-website-audit.
Spinners in single-page apps and forms #
Loading spinners show up most often in two places: single-page applications that fetch data after the initial page loads, and forms that submit to a server. In a single-page app, navigating between views often triggers a background request, and a spinner in the affected area, not the whole screen, tells users that section is updating while the rest stays usable. For forms, the moment someone clicks Submit, disabling the button and showing a small inline spinner reassures them the request is processing and prevents accidental double submissions, a common cause of duplicate orders or messages. The key in both cases is scope: spin only the part that is actually loading, so you never freeze the entire interface for a change that touched one panel. Handle failures gracefully too, replacing the spinner with a clear error and a retry option if the request fails. Designing these interaction details so applications feel responsive rather than stuck is part of the engineering care we bring to our /services/web-app-development page.
Best practices and our recommendation #
Use a loading spinner sparingly and only for short, indeterminate waits where you genuinely cannot show real progress. Show it promptly so the click feels acknowledged, but if a wait routinely stretches past a few seconds, treat that as a performance bug to fix rather than a spinner to prolong. Always pair the spinner with accessible status text and honour reduced-motion preferences. Where you can show structure, prefer a skeleton screen; where you know the length, prefer a progress bar; reserve the spinner for the middle ground. Make sure every spinner has a clear end state, including a graceful error message if the request fails, so nobody waits on a circle that will never stop. Above all, remember that the best loading experience is a page fast enough to need almost no spinner at all. If your spinners are covering for slow pages, our /services/speed-optimization and /services/web-design teams fix the cause rather than the symptom.
FAQ
What is the purpose of a loading spinner?
A loading spinner reassures users that a page or action is still working and has not frozen. It acknowledges their click instantly and covers a short, unpredictable wait while data loads or a form submits. Its job is psychological: a moving indicator prevents the anxiety of staring at a screen that appears completely stuck.
How long should a loading spinner show before it becomes a problem?
A spinner reassures for short waits of roughly one to a few seconds. Past that it stops meaning working and starts feeling stuck, prompting users to reload or leave. If your spinner routinely runs many seconds, the real issue is page speed, and the fix is optimizing performance rather than prolonging the animation.
Are loading spinners bad for user experience?
Not inherently. For short, indeterminate waits they help. They become bad when they hide a genuinely slow page, block the whole screen unnecessarily, flicker on very brief loads, or ignore accessibility. In many cases a skeleton screen or progress bar feels faster and communicates more, so the spinner is not always the best choice.
How do I make a loading spinner accessible?
Wrap it in an element with a role of status or an ARIA live region, and include visually hidden text like Loading so screen readers announce the busy state. Respect the prefers-reduced-motion setting by slowing or simplifying the animation, ensure sufficient contrast, and announce when loading finishes so everyone knows the result arrived.
What is the difference between a spinner and a progress bar?
A spinner is indeterminate: it shows that work is happening without saying how much remains, suiting short, unpredictable waits. A progress bar is determinate: it fills toward a known end, suiting waits of measurable length like file uploads. Use a spinner when you cannot estimate progress and a bar when you can.
Should I use a spinner or a skeleton screen?
Prefer a skeleton screen when you can show the shape of the content that is loading, because users often perceive it as faster and less like a stall. Use a spinner for brief, indeterminate waits where a placeholder would be overkill or where you cannot predict the layout of what is coming.
How Local Web Advisor checks this for you
Is your own website getting web design right?
Our free AI audit scans your site and tells you — in plain English — exactly what to fix for web design and seven other areas, with the business impact and the fix for each. No login needed to start.
Run my free website audit →Was this helpful?