FormatterHQ

CSS Loader & Spinner Generator

Build a lightweight loading spinner in pure CSS – ring, dual ring, bouncing dots, bars or pulse – set its color, size, thickness and speed, and copy the HTML and CSS.

Loading tool…
Ready.

How to use the CSS Loader & Spinner Generator

  1. Choose a Style: Ring, Dual ring, Bouncing dots, Bars or Pulse.
  2. Pick a Colour and set the Size (16–160px); for the ring styles also set Thickness.
  3. Set Duration of one cycle to control the speed, and switch the preview background between Light, Dark and Checker to check visibility.
  4. Copy or download the CSS and HTML tabs, or use Copy CSS + HTML to grab both at once.

A CSS loader generator for pure-CSS spinners

This CSS loader generator produces loading indicators built from a single element or a few empty spans, animated with @keyframes. There are no images, SVG files or JavaScript involved, so a spinner costs a few hundred bytes of CSS and renders sharply at any size and pixel density. Every loader animates transform (and opacity for the pulse), which browsers can usually run on the compositor without re-laying out the page.

You choose one of five styles, a color, a size and the length of one animation cycle. The markup is included in the HTML tab with role="status" and aria-label="Loading" already set.

Example: the default ring

.loader {
  width: 48px;
  height: 48px;
  border: 5px solid rgba(15, 118, 110, 0.2);
  border-top-color: #0f766e;
  border-radius: 50%;
  animation: loader-spin 1s linear infinite;
}

@keyframes loader-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .loader, .loader span { animation-duration: 3s; }
}
<div class="loader" role="status" aria-label="Loading"></div>

The ring is a circle with a faint track (the chosen color at 20% opacity) and one solid top border. Rotating the whole element makes the solid segment chase around the track.

The five styles and how they work

StyleMarkupTechnique
Ring1 elementTransparent-tinted border with a solid border-top-color, rotated linearly.
Dual ring1 elementborder-color: c transparent c transparent gives two opposite arcs, rotated linearly.
Bouncing dots3 spansEach dot scales from 0 to 1 and back; negative delays of about a third and a sixth of the cycle stagger them.
Bars4 spansBars scale vertically between 0.4 and 1 with staggered negative delays, like an equalizer.
Pulse1 elementA filled circle grows from scale 0 to 1 while fading from opacity 1 to 0.

Negative animation-delay values start each dot or bar partway through its cycle, so the loader looks staggered from the very first frame instead of waiting for the delays to pass.

Options explained

  • Colour – the main color; the ring's track is derived from it automatically.
  • Size – the outer width and height. Dots are sized at size ÷ 3.5 with a gap of size ÷ 5; bars are size ÷ 7 wide, so everything scales together.
  • Thickness – border width for Ring and Dual ring only (1–20px); the control is hidden for other styles.
  • Duration of one cycle – 0.3 to 4 seconds. Around 0.8–1.2s feels active without looking frantic.

Accessibility built in

role="status" makes the loader a polite live region, so assistive technology can announce it without interrupting the user. Some screen readers announce a label on an empty element less reliably than real text, so for important waits put visually hidden text such as "Loading…" inside the element. Also mark the region that is updating with aria-busy="true" and remove it when content arrives.

The CSS ends with a prefers-reduced-motion query that slows every loader to a 3-second cycle for users who ask their operating system to reduce motion. The spinner still shows that something is happening, just without rapid movement. If you prefer, replace it with animation: none and a static "Loading…" label.

Tips and common mistakes

  • Delay the spinner. Showing a loader for a 150ms request just causes a flash. Reveal it only if the wait passes about 300ms.
  • Hide it properly. Remove the element or set the hidden attribute when loading ends; an invisible but running animation still uses CPU.
  • Check keyframe names. The generated names (loader-spin, loader-bounce, loader-bars, loader-pulse) are global. Rename them if your stylesheet already uses those names.
  • Center it with the parent. The loader has no margins. Use display: grid; place-items: center on the container.
  • Mind contrast. A thin, light ring on a white page can be hard to see. Increase thickness or darken the color, and check it against the Dark preview background if your site has a dark theme.

CSS loader vs GIF or SVG spinner

An animated GIF is a separate request, cannot change color with your theme and looks blurry on high-density screens. An inline SVG spinner is flexible but longer to write. A pure CSS loader is the smallest option and can take its color from a CSS variable. For custom motion beyond these five styles, the CSS animation generator gives you keyframe presets, and the cubic-bezier generator lets you replace ease-in-out with your own timing curve.

Privacy

The loader code is generated locally in your browser. No settings or code are sent to a server.

Frequently asked questions

How do I center a CSS loader on the page?
Put the loader in a container with display: grid; place-items: center; and give the container the height you want, such as min-height: 100vh for a full-page loader. Flexbox with justify-content and align-items set to center works too.
How do I show and hide the spinner with JavaScript?
Toggle the hidden attribute, for example loader.hidden = false before a fetch and loader.hidden = true in its finally block. Hidden elements are not rendered, so their animation stops using resources.
Can I change the spinner color with a CSS variable?
Yes. Replace the hex values in the copied CSS with var(--loader-color) and define the variable on :root or a parent element. For the ring track, use color-mix(in srgb, var(--loader-color) 20%, transparent) in browsers that support it.
Why does my loader wobble while spinning?
A ring wobbles when its width and height differ or when it sits in a flex container that stretches or shrinks it. Keep width and height equal and add flex-shrink: 0 if the loader is a flex item.
Do CSS spinners slow down the page?
Loaders that animate only transform and opacity are cheap because the browser can usually handle them on the compositor. Performance problems usually come from running many spinners at once or leaving hidden ones animating.

Last updated October 3, 2026

Related tools

CSS Animation Generator Generate CSS @keyframes animations — fade, slide, zoom, bounce, pulse, shake, spin and more — with duration, delay, easing and loop controls. CSS Background Pattern Generator Generate repeating CSS background patterns — stripes, polka dots, checkerboard, grid, zigzag and more — using only gradients, no images. CSS Border Radius Generator Set border-radius per corner in px or %, or shape organic blobs with the 8-value "fancy" border-radius syntax. Live preview and copyable CSS. CSS Box Shadow Generator Design layered CSS box-shadows with sliders for offset, blur, spread, colour and opacity. Supports inset shadows, presets and a Tailwind class. CSS Button Generator Design a CSS button with colours, gradient, padding, radius, border, shadow and hover/focus states, then copy clean HTML and CSS. CSS Clamp Generator (Fluid Typography) Calculate a CSS clamp() value that scales font size or spacing smoothly between two viewport widths, with a table of computed sizes. CSS Pretty Print Opinionated CSS pretty print with Prettier: normalises case, leading zeros, quotes and semicolons so a team's stylesheets look alike. CSS Scrollbar Generator Style scrollbars for Chrome, Edge and Safari (::-webkit-scrollbar) and Firefox (scrollbar-color) at once, with a scrollable live preview. CSS Gradient Text Generator Fill headings with a colour gradient using background-clip: text. Pick two or three colours and an angle and copy cross-browser CSS. CSS Text Shadow Generator Generate CSS text-shadow effects — soft shadows, hard 3D offsets and neon glows — with live preview on your own text, then copy the CSS. CSS to LESS Converter Convert CSS to LESS online. Rules sharing a selector are nested automatically. CSS to SASS Converter Convert CSS to SASS online. Rules sharing a selector are nested automatically.