By Tim King · Updated
CSS Loading Spinner Generator
Ring, Dots, Bars and Pulse Loaders
OneTask is free, with no sign-up, and built by one person.
If this tool saved you time, a coffee helps keep new ones coming.
How the Loading Spinner works
This CSS loading spinner generator builds rings, dots and bars. Pick a loader shape, size it, colour it and set how fast one cycle runs, then copy a single element and a few lines of CSS. Every style here is drawn by the browser from borders, circles and bars, so there is nothing to download and it scales cleanly to any size.
CSS loading spinner: shapes and timing
The Ring is the workhorse loader: a square element with a thick border, rounded into a
circle, where only the top edge is coloured. Rotating it once per cycle with linear timing
gives the familiar spinning arc. The track colour fills the other three sides; set it to match
your background if you only want the moving segment visible. Dual ring colours the top and
bottom edges and leaves the rest transparent, which reads as two chasing arcs. Dashed arc does
the same job with an SVG circle and stroke-dasharray, which gives you round line caps and a
softer look that borders cannot manage.
Dots and Bars are sequences: each piece runs the same keyframes but starts at a
different point, using negative animation-delay so nothing waits for the first cycle before
joining in. The delays are expressed as fractions of the cycle time with calc(), so changing
the speed keeps the pieces evenly spaced. Pulse is a single disc that grows from nothing and
fades out; Ripple layers two expanding rings half a cycle apart, which works well as a
"searching" or "waiting for connection" indicator.
The cycle time is how long one full turn or one complete wave takes. Around one second feels
neutral; faster loaders suggest urgency and slower ones feel calm but can look stuck if the
motion is subtle. A spinner should always be accompanied by a role="status" and an accessible
label, which the generated HTML includes, so screen readers announce that something is loading
rather than encountering an empty element.
Because these are pure CSS, they keep spinning even while the main thread is busy, which is
exactly when you need a loader to keep moving. If your users may have reduced-motion preferences
turned on, consider swapping the spinner for a static "Loading…" label inside a
prefers-reduced-motion media query.
FAQ
Which spinner is the most compatible?
The Ring. It is one element, one border and one rotation keyframe, and it has worked in every browser for a decade. The dashed arc uses SVG, which is equally well supported but adds a few more lines.
How do I put it on a button?
Set the size to the button's line height, about 16 to 20 pixels, and place the element inline before the label. Setting the track colour to transparent keeps the button's own background showing through.
Does the spinner keep going if the page is busy?
Yes. CSS animations run on the compositor, so a ring keeps turning while JavaScript is blocking the main thread, which is exactly when you need the reassurance.
Should it stop for users with reduced motion on?
Ideally replace it with a static "Loading…" label inside a prefers-reduced-motion: reduce
media query. A slow, small spinner is generally tolerated, but a large fast one is not.
See also: all Shadows & Motion tools, Layout & Spacing, Shapes & SVG, UI Components, Forms & Inputs, Colour.
Related tools
Easing Comparison
Run two CSS easings side by side and copy the winner.
Keyframe Animator
Build and preview a CSS @keyframes animation from three stops.
Progress Bar Generator
Generate a linear, striped, animated or circular CSS progress bar and copy the code.
Text Animation
Animate a headline letter by letter and copy the CSS.
CSS Bounce Animation
A bouncing ball with optional squash and stretch.