Loading indicators that announce themselves
A bare spinning div is invisible to a screen reader. These come with the role and the name that make them mean something.
Loading indicators that announce themselves
A bare spinning div is invisible to a screen reader. Every spinner here comes with the role and the accessible name that make it mean something.
Reduced motion: slower, not stopped
Stopping the animation entirely leaves a shape that looks like a frozen page, which is worse than no indicator. Slowing it to two and a half seconds keeps the signal and removes the fast repetitive motion that causes the problem.
WCAG 2.2.2 only requires that motion lasting more than five seconds can be paused, so a spinner is technically compliant either way. Respecting the preference anyway costs one media query.
role="status" makes the region a live region with a polite announcement. Without an accessible name it announces nothing useful, so aria-label="Loading" is not optional.
A spinner is an admission
It says the interface does not know how long this will take. Where you do know — a file upload, a multi-step process — a progress bar tells the user far more, and where the wait is short a skeleton preserves the layout instead of replacing it.
Spinners are right for genuinely indeterminate waits, and they are used far more widely than that.
Do not show one immediately
A spinner that appears and disappears within 200 milliseconds reads as a flicker and makes the interface feel less stable, not more responsive. Delaying it by around 300ms means fast responses never show one at all.