Animated CSS Loader Generator
Generate full CSS for animated loaders: spinner, dots, progress bar, conic ring.
CSS loaders and spinners: feedback during async work
A loader (also called spinner, activity indicator or busy indicator) is a small piece of UI that signals to the user that the interface is doing something they cannot directly observe — fetching data, processing a payment, uploading a file. Without it, a one-second delay feels like a freeze and users start clicking the same button again, hitting reload, or walking away. With it, the same delay feels routine. CSS loaders implement that feedback with pure HTML and a @keyframes rule, so there is no JavaScript runtime cost and no image to download.
The canonical shape is the rotating border ring. You draw a circle with a transparent border, paint one side with a solid colour, and animate transform: rotate from 0deg to 360deg on an infinite linear loop. Because transform is a composited property, the browser can animate it on the GPU without re-running layout or paint, so the spinner stays smooth even when the main thread is busy parsing the JSON it is waiting for.
.spinner {
width: 32px; height: 32px;
border: 3px solid #e5e7eb;
border-top-color: #2563eb;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
Loader families and when to pick each one
- Spinner / ring — generic "something is happening", indeterminate duration. The default choice for under-3-second waits.
- Dots — three or four dots scaling or bouncing in sequence. Friendly, often used in chat "typing" indicators.
- Bars — pulsing vertical bars. Suits audio/equaliser themes and music players.
- Progress bar — use only when you can measure progress (file upload, multi-step form). The native
<progress>element is accessible by default. - Skeleton screen — a greyed-out preview of the final layout, ideal for content pages where the structure is predictable.
Performance tips
Animate transform and opacity — never top, left, width or height, which trigger layout on every frame. Add will-change: transform only on long-lived loaders and remove it afterwards; the hint reserves a compositor layer and over-using it can hurt scrolling. conic-gradient lets you draw a colour wheel without SVG, and pairing it with mask hollows out the centre to make a ring.
Accessibility and UX
Every loader should expose role="progressbar" or an aria-label="Loading" so screen readers announce the wait, and the container should set aria-busy="true" until the content arrives. Always wrap the animation in @media (prefers-reduced-motion: reduce) and fall back to a static dot or text — users with vestibular disorders can be physically nauseated by spinning indicators. As for duration: under 200 ms feels instant and needs no loader; 200 ms–1 s a spinner is fine; 1–10 s a progress bar with a percentage; more than 10 s an explicit ETA and the ability to cancel.
FAQ
CSS, SVG or Lottie — which should I use? CSS for simple geometric loops (rings, bars, dots) — smallest payload, no extra request. SVG for shapes with paths CSS cannot draw (logos, mascots). Lottie for After-Effects-grade animations exported as JSON, when polish matters more than weight.
Is there a native HTML alternative? Yes, <progress value="…" max="100"> for determinate progress. It is accessible out of the box and can be styled with CSS.
Why does my loader stutter on mobile? Usually it animates a non-composited property (e.g. background-position or width), or it lives inside a parent that recalculates layout each frame. Switch to transform and make sure the loader's container does not change size while it runs.
How small can a loader be? 16 px is the practical minimum — below that, the user cannot tell a spinner from a static dot. The sweet spot is 24–48 px depending on the surrounding UI.
Related Tools
Skeleton CSS Loader Generator
Generate animated skeleton loader CSS (shimmer) for content placeholders.
Animated CSS SVG Blob Generator
Generate an SVG blob with CSS morphing animation, ready to paste into landing pages and website sections. Create organic, dynamic backgrounds and copy the code.
CSS Clip-Path Polygon Generator
Generate the CSS clip-path polygon() property by adjusting points visually. Clip images and divs into custom shapes and copy the ready-to-use code.