.loader {
width: 60px;
height: 60px;
border: 4px solid #7c6aff33;
border-top-color: #7c6aff;
border-radius: 50%;
animation: spin 0.80s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}CSS Loading Spinner Generator — 36 Pure CSS Loaders
What's included
Features
About this tool
Generate Any CSS Loading Animation in Seconds — 36 Pure CSS Loaders, No JavaScript, Copy HTML and CSS
You need a loading spinner for a form submission, an API fetch, or a full-page loader — and you don't want to pull in a library or write @keyframes from scratch. Pick one of the 36 styles, set your color and size, and copy the CSS and HTML in one click.
36 pure CSS loader styles covering every use case: classic spinners (Ring, Arc, Comet), multi-element animations (Dots, Bars, Wave, Equalizer), expanding patterns (Pulse, Ripple, Sonar, Target), orbital mechanics (Orbit, Chase, Spiral, Propeller, Windmill, Atom), shape-morphing (Morph, Flip, Diamond, Hourglass), organic motion (Jellyfish, Bounce, Pendulum, DNA), progress indicators (Shimmer), clock-inspired (Clock), grid patterns (Grid, Dot Ring, Square Chase), specialty styles (Neon, Glitch, Typing), and notification badges (Wifi). All built with CSS @keyframes on plain div elements — no JavaScript, no image files, no library dependencies.
GPU-composited animations stay smooth at 60fps even when the main JavaScript thread is busy processing data. Set the primary and secondary colors independently, adjust size from 20px inline button spinners to 120px full-page overlays, and tune the speed multiplier from 0.5× to 3×. The tool exports HTML, CSS, or both combined — plus a React format that wraps the loader in a functional component with scoped styles. Every loader adapts its dimensions and timing automatically to whatever size you set.
Step by step
How to Use
- 1Select a loader styleClick any loader chip in the left sidebar — each chip shows a live miniature preview of that loader style animating with your current colors. The chips are grouped in a grid covering all 36 styles. Clicking a chip switches the large center preview to that style immediately.
- 2Set the primary and secondary colorsIn the controls bar above the preview, click the Primary color swatch and pick a color from the browser color picker, or type a hex value into the text input. The Secondary color controls the track ring, second arc, or alternate elements where applicable. Both colors update all 36 mini-previews in real time.
- 3Adjust size and speedDrag the Size slider from 20px (compact inline button spinner) to 120px (large full-page loader). Drag the Speed slider from 0.5× (slow and calm) to 3× (fast and urgent). The Size and Speed values scale all animation timings proportionally so the loader always looks correct at any size.
- 4Preview on light or dark backgroundClick the Dark or White background preset buttons to test the loader on dark and light surfaces. Click the color picker swatch next to the background buttons to choose a fully custom background color. This helps verify contrast between the loader color and the background it will sit on.
- 5Copy the codeIn the code panel below the preview, switch between the CSS tab (just the @keyframes and layout styles), HTML tab (just the DOM markup), Both tab (complete self-contained snippet), or React tab (a functional component that inlines the styles). Click Copy to copy the selected output to your clipboard.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
Use a pure CSS spinner built with @keyframes — no JavaScript library or image file needed. Pick a style here, set your color and size, then copy the HTML and CSS. Paste the CSS into your stylesheet and the HTML wherever you want the loader to appear. Show or hide it by toggling display: none / display: flex via JavaScript or a CSS class.
Yes — the animation itself is entirely CSS-driven using @keyframes. No JavaScript is needed to animate the loader. You may use JavaScript to show or hide it (toggle a class or display value), but the spinning, pulsing, or bouncing runs purely in CSS. The animations stay smooth at 60fps even when the JavaScript thread is busy.
Scale the Ring or Dots loader to 16–20px using the Size slider. Paste the HTML inside the button element alongside the label text. Set display: inline-flex; align-items: center; gap: 8px on the button. Disable the button when the spinner appears to prevent double-submit. Restore the original label on success or error.
Yes. Use the Primary Color picker to set the main loader color (the spinning arc, dots, or bars). Some styles also have a Secondary Color for the background track. The Size slider scales from ~16px inline to ~80px full-page. The Speed control adjusts animation-duration — lower values for urgency, higher for calm ambient indicators. All settings update the preview and exported code in real time.
Add role="status" and aria-label="Loading" to the outer loader element. This tells assistive technology the region is a live status indicator. Optionally add a visually hidden text element with aria-live="polite" that updates to "Loading..." when the spinner appears — this announces the state change to screen reader users without requiring them to navigate to the element.
Paste the HTML as JSX into your component (replace class with className). Paste the CSS into your stylesheet or CSS module. To conditionally show it: {isLoading && <div className="loader-ring"><div></div>...}. For styled-components or Tailwind, copy the keyframe values and recreate the animation using the appropriate syntax.
36 styles across multiple categories: Spinners (Ring, Arc, Comet, Neon), Multi-element (Dots, Bars, Wave, Equalizer, Wifi), Expanding (Pulse, Ripple, Sonar, Target), Orbital (Orbit, Chase, Spiral, Propeller, Windmill, Atom), Morphing (Morph, Flip, Diamond, Hourglass), Organic (Jellyfish, Bounce, Pendulum, DNA), Grids (Grid, Dot Ring, Square Chase), Specialty (Glitch, Typing, Clock, Heartbeat, Shimmer). All are pure CSS with @keyframes — no JavaScript or image files.
Yes — completely free, no account required. All processing runs in your browser. No code is sent to any server.
Wrap the loader in a full-screen overlay: position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 9999; background: rgba(255,255,255,0.8). The fixed positioning ensures it covers the entire viewport regardless of scroll position. The semi-transparent background darkens the page underneath to indicate it's not interactive while loading. Set a high z-index to ensure it renders above modals and dialogs. Remove the overlay from the DOM (or set display: none) once loading is complete.
The Ring loader at 16–18px is the standard choice for inline button spinners — it's compact, universally recognizable, and renders cleanly at small sizes because its border-based construction stays sharp. Set the ring border color to match the button text color (usually white for primary buttons) and the track color to a semi-transparent variant of the same color. For text buttons, Dots at 14px works well because it reads as a status indicator without taking up much horizontal space. Avoid Grid and Roller styles at small sizes — they lose definition below 20px.
A skeleton loader uses the Pulse or Shimmer pattern — a gradient that sweeps across placeholder shapes. Use the Pulse style from this generator as a base, then apply it to div elements shaped like your content: a rectangle for a text line, a circle for an avatar, a wide rectangle for a header. Animate a linear-gradient overlay from left to right using @keyframes to create the shimmer effect: background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent); and animate background-position. The result looks like a low-fidelity outline of the actual content layout that will load.