CSS Loading Spinner Generator
Pick from 20 pure-CSS loaders, customize size, color, and speed, then copy the HTML and CSS.
Processed locally in your browserSpinner controls
Spinners (20)
Pure CSS — zero JavaScriptSelected spinner: Classic Ring
@media (prefers-reduced-motion: reduce) block that pauses the animation.Code
.spinner-classic-ring {
width: 64px;
height: 64px;
border: 6px solid #E5E7EB;
border-top-color: #10B981;
border-radius: 50%;
animation: spinner-classic-ring-anim 1s linear infinite;
}
@keyframes spinner-classic-ring-anim {
to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
[class^="spinner-"], [class^="spinner-"] * {
animation: none !important;
opacity: 0.7;
}
}Unlock the full toolkit
Batch processing, no ads, higher limits, and API access.
How to Use
1. Pick a spinner from the gallery — the live preview reacts to your color and size while you browse. 2. Tweak size (16–200 px), speed (0.3–3 s), foreground color, and the optional background color. 3. Toggle the `prefers-reduced-motion` override if you want the exported CSS to disable the animation for users who request reduced motion. 4. Open the HTML and CSS tabs to inspect the snippet, or click "Copy all" to grab both at once. 5. Paste into your project — the class names are scoped (e.g. `spinner-classic-ring`) so they will not collide. Pair with the CSS Gradient Generator for richer loading screens.
Features
- ✓20 hand-crafted spinner styles — rings, dots, bars, ripples, orbit, atom, radial wave, and more
- ✓Pure CSS keyframes — zero JavaScript dependencies
- ✓Live preview reacts to size, color, background, and speed in real time
- ✓Color pickers for foreground and background (where applicable)
- ✓Sliders for size (16–200 px) and speed (0.3–3 s)
- ✓Optional `prefers-reduced-motion` override appended to the exported CSS
- ✓Copy HTML, CSS, or both with one click
- ✓Scoped class names (`spinner-…`) and prefixed keyframes — no collisions in your project
- ✓Each spinner ships with `role="status"` and `aria-label="Loading"` for screen readers
- ✓Fully client-side — no signup, no upload, runs in your browser
Frequently Asked Questions
- How is a CSS spinner different from an SVG or Lottie loader?
- A CSS spinner is built from HTML elements styled with CSS keyframes — it is rendered by the browser layout engine, animates on the GPU, and ships with zero JavaScript or asset weight. An SVG spinner is a vector file that animates via `<animate>` tags or CSS — flexible for complex paths but heavier to author. A Lottie loader is a JSON animation rendered by a JavaScript runtime — it supports very rich animations (Bodymovin from After Effects) at the cost of a runtime dependency. For simple loading states, pure CSS is the lightest, fastest, and most accessible option.
- How do I make a loading spinner accessible?
- Wrap the spinner element in a container with `role="status"` and a label such as `aria-label="Loading"` or visually hidden text inside (`<span class="sr-only">Loading…</span>`). When the loading state ends, remove the spinner from the DOM or update the label so screen readers announce completion. Every snippet generated by this tool already includes `role="status"` and `aria-label="Loading"` on the root element.
- What does `prefers-reduced-motion` do for spinners?
- The `prefers-reduced-motion: reduce` media query lets users opt out of non-essential motion at the OS level (macOS, iOS, Windows, Android, GNOME). For spinners, the recommended pattern is to either disable the animation or fall back to a static state. Toggle the option in this tool to append a `@media (prefers-reduced-motion: reduce) { animation: none; }` block to the exported CSS — the spinner stays visible (so users still know loading is in progress) but stops moving.
- Are CSS animations performant on mobile?
- Animations of `transform` and `opacity` are GPU-accelerated in every modern browser and remain smooth on low-end mobile devices. Avoid animating layout properties such as `width`, `height`, `top`, or `left` — they trigger layout recalculation on every frame. All spinners in this tool animate `transform` and `opacity` only, so they stay at 60 fps even on mid-range Android phones.
- How do I customize a spinner beyond the controls in this tool?
- The exported CSS is plain — change any value to suit your design. Common tweaks: increase or decrease the border thickness on ring spinners, swap `linear` for `ease-in-out` to soften the rhythm, raise the count of dots/bars in the HTML and add more `nth-child` delay rules, or stack the spinner inside a backdrop using a solid `<div>` with `position: fixed`. Use the CSS Gradient Generator to build a tinted overlay for a full-screen loader.
- Will the class names collide with my own CSS?
- Each spinner uses a scoped class name like `spinner-classic-ring` or `spinner-dual-ring`, and every keyframe is prefixed (`spinner-classic-ring-anim`, `spinner-dual-ring-out`, etc.). The `spinner-` prefix is unlikely to clash with most design systems, but if you already use it for your own components, just rename the classes after copying — there are only one or two per snippet.
- Can I use these spinners in a Tailwind project?
- Yes. Drop the generated CSS into your global stylesheet (or a `@layer components` block) and use the class on any element: `<div className="spinner-classic-ring" />`. Tailwind will not strip the keyframes since they live in a regular stylesheet, not in the Tailwind config. For a deeper Tailwind integration, you can lift the keyframes into `tailwind.config.js` under `theme.extend.keyframes` and `theme.extend.animation`, then expose the spinner as a utility class.