Choosing the right loader for the wait

The type of loader should match how long the wait will be and whether you can measure it. For waits under about a second, showing nothing at all is often best — a spinner that flashes for 300ms reads as a glitch rather than progress.

For short indeterminate waits, a spinner or bouncing dots works. For anything you can measure, use a progress bar: knowing that a task is 70% done is far less stressful than watching an endless spin. And when you're loading content into a known layout, a skeleton screen beats both.

Why skeleton screens feel faster

Skeletons outperform spinners for the same wait because they set expectations. A spinner says "something is happening somewhere"; a skeleton shows the shape of what's arriving, so the eye already knows where the headline and the image will land. When the content appears, it slots into place instead of replacing an unrelated animation.

The rule that makes them work: size each placeholder bar like the content it stands in for. Skeletons that don't match the final layout cause a jump when the real content loads — which is exactly the layout shift you were trying to avoid.

Accessibility: loaders need to be announced

A purely visual loader is invisible to a screen reader user, who gets silence and no indication anything is happening. Give the element role="status" and an aria-label such as "Loading results", and assistive technology will announce it politely without interrupting.

Also respect prefers-reduced-motion. Continuously spinning elements can trigger discomfort for people with vestibular disorders — a static or fading indicator is a reasonable substitute, and the reduced-motion snippet in our how-to guide handles this globally.

Keeping loaders cheap

Every loader here animates only transform, opacity or background-position, which browsers composite on the GPU. That matters more than usual for loaders: they run precisely when the main thread is busy fetching and parsing, so an animation that requires layout work will stutter exactly when it's most visible.

Frequently asked questions

When should I use a skeleton screen instead of a spinner?

Use a skeleton whenever you are loading content into a layout you already know — lists, cards, articles. It sets expectations about what is arriving and reduces perceived wait. Use a spinner for short indeterminate waits where the resulting layout is unknown.

Do CSS loading animations need JavaScript?

No. Every loader here is pure CSS and animates as soon as it is in the DOM. JavaScript is only needed to add or remove the element when your request starts and finishes.

How do I make a loading spinner accessible?

Give it role="status" and an aria-label such as "Loading results" so screen readers announce it. Also honour prefers-reduced-motion, since continuous spinning can cause discomfort for people with vestibular disorders.

Related categories

← Back to all 72 CSS animations