Embed this tool on your site
About this tool
Loading spinners tell users the interface is working, not frozen — a critical feedback mechanism for API calls, form submissions, and file processing. Pure CSS spinners need no GIF or SVG asset: a styled element animates indefinitely via @keyframes. The CSS Spinner Generator offers five presets — Border, Dual Ring, Dots, Pulse and Bars — and three controls: Size (16–140px), one Color, and Speed in seconds (0.2–4). Ring thickness is derived from the size, and the Border preset draws its track in the same color at low opacity (the hex color with 33 appended as alpha). The live preview updates as you change values, and the output includes the .spinner rule plus its @keyframes sp-rot block, ready to paste. The Dots preset expects one <i> element inside the spinner for its middle dot.
Why use it
Pure CSS: No JavaScript, no animated GIF, no SVG file dependency. Most presets are a single div with a border or background and an animation; the Dots preset adds one <i> child. Nothing extra is downloaded.
Speed Control: The Speed field sets the duration of one cycle in seconds, from 0.2 to 4. Fast spinners (0.6–0.8s) convey urgency for quick operations; slower spinners (1.2–1.6s) feel more relaxed for longer background tasks.
Auto Thickness: Ring thickness follows the size — about one ninth of the diameter for Border and one tenth for Dual Ring, never below 2px — so small inline spinners stay light and large overlay spinners stay visible.
One Color: A single color picker drives every preset. The Border preset reuses it for the track at low opacity by appending 33 to the hex value, so the arc and track always match.
Five Presets: Border is the classic rotating arc; Dual Ring colors the top and bottom arcs of one rotating ring; Dots scales three dots in sequence; Pulse grows and fades a filled circle; Bars animates three gradient bars. All share the same size, color and speed controls.
Copy + Keyframes: The output includes both the .spinner rule and its @keyframes sp-rot block. Forgetting the keyframes is the most common reason a spinner does not animate after pasting — this generator outputs both together so nothing is missing.
How to use
- Pick a preset: Border, Dual Ring, Dots, Pulse, or Bars
- Drag the Size slider (16–140px); ring thickness scales with it automatically
- Choose one Color — the Border preset uses it for the moving arc and a faint low-opacity track
- Set Speed in seconds (0.2–4) for one animation cycle
- Preview the live spinning animation to verify the look and feel
- Click Copy CSS to capture the .spinner rule plus its @keyframes sp-rot block
When it helps
- When a button needs an inline spinner to replace its label during a form submission or async operation
- When a card or section is loading data and needs a centered placeholder spinner
- When building a full-page loading overlay for an initial data fetch on a dashboard
- When an image or content area is lazy-loading and needs a lightweight placeholder animation
- When replacing an animated GIF spinner that no longer matches the updated color scheme
- When building a design system and need a standardized, tokenized loading indicator component
Examples
InputPreset: Border, Size: 40px, Color: #6366f1, Speed: 0.8s
Expected result.spinner {
width:40px;
height:40px;
border:4px solid #6366f133;
border-top-color:#6366f1;
border-radius:50%;
animation:sp-rot 0.8s linear infinite
}
@keyframes sp-rot{to{transform:rotate(1turn)}}
InputPreset: Border, Size: 56px, Color: #f5c842, Speed: 1s
Expected result.spinner {
width:56px;
height:56px;
border:6px solid #f5c84233;
border-top-color:#f5c842;
border-radius:50%;
animation:sp-rot 1s linear infinite
}
@keyframes sp-rot{to{transform:rotate(1turn)}}
InputPreset: Dual Ring, Size: 64px, Color: #4b5563, Speed: 1.4s
Expected result · Scroll for more.spinner {
width:64px;
height:64px;
border:6px solid transparent;
border-top-color:#4b5563;
border-bottom-color:#4b5563;
border-radius:50%;
animation:sp-rot 1.4s linear infinite
}
@keyframes sp-rot{to{transform:rotate(1turn)}}
Tips
- Always use linear easing — ease or ease-in-out creates an uneven rotation that looks broken on circular spinners
- Define @keyframes spin globally once and reference it in multiple spinner classes rather than redefining the keyframes per component
- Respect @media (prefers-reduced-motion: reduce) by stopping the animation — users with vestibular disorders can experience discomfort from rotating elements
- Colored arc effect comes from border-top (or one side) having a different color than the remaining three borders — not from a gradient
- Add will-change: transform to the spinner element for consistent GPU-accelerated rendering on pages with many simultaneously animated elements
Frequently Asked Questions
How does a CSS-only spinner work without JavaScript?⌄
A spinner is a circular div with a complete border in a track color and one side (typically border-top) in the accent color. The @keyframes spin animation rotates the element 360 degrees continuously using transform: rotate(). No JavaScript is needed since the animation is entirely CSS-driven.
What is the best animation duration for a loading spinner?⌄
0.8–1.2 seconds per rotation is the conventional range for spinners. Faster than 0.6s starts to look frantic and may be hard to follow visually. Slower than 1.5s can feel sluggish. Use faster speeds for perceived quick operations and slower speeds for genuinely long processes.
Should I use linear or ease-in-out for spinners?⌄
Always linear. ease-in-out creates a perceptible acceleration and deceleration that looks mechanical and uneven on a rotating circle. Linear timing produces a smooth, constant rotation that reads naturally as a spinning object.
How do I make a spinner respect prefers-reduced-motion?⌄
Wrap the animation declaration in a @media (prefers-reduced-motion: no-preference) block, or replace the animation with a static indicator inside @media (prefers-reduced-motion: reduce). This stops the rotation for users who have requested reduced motion in their OS settings.
Can I add multiple colors to a spinner?⌄
A single border-based spinner supports two colors: the track and the accent arc. For multi-color spinners, use SVG with stroke-dasharray and multiple animated circle elements, or use conic-gradient on a rotating element for a rainbow arc effect.
Why does my spinner stutter or jitter?⌄
Stuttering usually means the animation is running on the main thread. Add will-change: transform to the spinner element to promote it to its own compositor layer and enable GPU-accelerated rendering. Also ensure no synchronous JavaScript is blocking the main thread during the animation.
How is animation different from transition?⌄
Transitions animate between two states triggered by a state change (hover, class toggle). Animations run autonomously on a defined timeline without needing a trigger, support multiple keyframes, and can loop, reverse, or delay independently.
Can the spinner be paused on hover?⌄
Yes. Add animation-play-state: paused to the :hover state to freeze the rotation when the cursor moves over the spinner. This is occasionally used to display a cancel action on hover, though pausing a loading spinner is uncommon in typical UI patterns.
Glossary
- Keyframes
- CSS @keyframes rules that define the intermediate steps of an animation by specifying property values at percentage points (0%, 50%, 100%) or from/to keywords along the animation timeline.
- Animation Duration
- The time it takes to complete one full cycle of a CSS animation, set with animation-duration in seconds or milliseconds. For spinners, this is the time for one full 360-degree rotation.
- Linear Easing
- An animation timing function that progresses at a constant rate from start to finish with no acceleration or deceleration, essential for smooth continuous rotation effects.
- Border Radius
- When set to 50%, turns a square element into a circle. Applied to a spinner div to create the circular ring shape that the border-based animation technique requires.
- Infinite Loop
- Animation-iteration-count: infinite keeps a CSS animation running continuously without stopping. Spinners rely on this to maintain rotation for the entire duration of a loading state.
- Loader
- A UI element that indicates background processing or data fetching to prevent users from thinking the application has frozen. CSS spinners are the most lightweight implementation of this pattern.
A LITTLE HELP. A LOT DONE.
Good tools.
Great flow.
Your shortcut to the everyday. Create, convert, calculate,
and get back to what you love.
✳
✳
✓ Free to use✓ No sign-up✓ 500+ possibilities