Why is a CSS spinner better than an animated GIF?
It is a few hundred bytes instead of several kilobytes, it scales to any size without going blurry, it inherits your brand color from one hex value, and it renders on the compositor rather than decoding image frames. It also has no extra network request, which matters because a loader is shown precisely when the network is the bottleneck.
How do I make the spinner accessible?
Wrap it in an element with role="status" and put visually hidden text like "Loading" inside, so a screen reader announces the wait instead of nothing. The generator does not add that markup for you.
Should I hide the loader for users who prefer reduced motion?
Yes, or at least tame it. Wrap the animation in a @media (prefers-reduced-motion: reduce) block that sets animation: none and shows a static indicator instead. An infinite spin is the classic trigger for motion sensitivity.
The bouncing dots look out of sync after I edited the CSS. What happened?
The dots and bars loaders rely on hardcoded animation-delay values that were computed from the speed you chose. Change the animation duration and the delays no longer land at the right fraction of the cycle. Regenerate at the new speed instead of hand-editing the duration.
Can I center the loader on the page?
The snippet only styles the loader itself. Put it in a flex container with align-items: center and justify-content: center, or use position: fixed with inset: 0 for a full-screen overlay. The dots and bars loaders are inline-flex, so they sit on the text baseline unless you wrap them.
Which loader style is the safest default?
The ring. It is a single element, it reads as a spinner at any size from 24px up, and it has the lowest risk of looking broken if your CSS is later overridden. Dots and bars need three or four child spans, and the pulse relies on opacity animating to 0, which some people read as the element disappearing rather than loading.