Skip to content
Back

CSS Loader Generator

Create CSS-only loading spinners with your own size, colour and speed.

Build a loading spinner without images or JavaScript

CSS Loader Generator gives you a loading indicator made only of HTML and CSS: a ring spinner, a dual ring, three bouncing dots, bars, a pulse, a ripple, an indeterminate progress bar or a dashed circle. You set the size, colour, thickness and speed, and copy two snippets — the markup and the stylesheet.

The markup is announced to screen reader users, and the CSS respects the reduced-motion setting on your visitors’ devices. All eight styles are previewed live on the page with your settings, and nothing is uploaded.

How to make a CSS loader

  1. Choose a style in the gallery. The styles are radio buttons, so you can also move between them with the arrow keys.
  2. Set the size in px. For the progress bar it is the width; for the bouncing dots it is the width of the row.
  3. Pick a colour with the picker or type a hex code, and set the thickness where the style has one — ring thickness, bar width, bar height or dash thickness.
  4. Set how long one cycle of the animation takes, in seconds. Smaller numbers are faster.
  5. Choose what happens when a visitor has asked for reduced motion: slow it down to a third of the speed, or stop it.
  6. Copy the HTML to where the loader should appear and the CSS into your stylesheet.

What you copy

  • HTML: a div with the class loader and role="status", any dots or bars the style needs, and a “Loading…” label that is hidden visually but read by screen readers.
  • CSS: the loader’s rules, a visually-hidden rule for the label, @keyframes with a name specific to the style (such as loader-ring-spin), and a prefers-reduced-motion block.
  • One speed setting: every animation and delay is based on the --loader-speed custom property, so you can change the speed later in one place.

When a CSS-only loader fits

  • Buttons and forms: show progress while a form submits or a request is running.
  • Page and panel placeholders: fill a space while content loads, without waiting for an image to arrive first.
  • Lightweight sites: no script, image or library is needed for the animation itself; your own code only adds or removes the element.

Tips for loaders people can live with

  • Remove it when you’re done: take the element out of the page (or hide it) as soon as the content arrives, so screen readers stop treating it as current.
  • Change the label to match the task: “Saving…” or “Loading results…” tells people more than a generic word.
  • Check the colour against its background: a loader is a graphic, so aim for at least 3:1 contrast. The Color Contrast Checker shows the ratio.

Accessibility built into the snippets

role="status" and the hidden label

A spinning shape means nothing to someone who can’t see it. role="status" marks the element as a polite live region, and the visually hidden “Loading…” text gives it words, so assistive technology can tell people that something is happening.

prefers-reduced-motion

Some people turn on a reduce-motion setting because movement on screen makes them unwell or distracts them. The generated CSS checks for it and either slows the animation to a third of its speed (still showing that work is in progress) or stops it. The previews on this page stop when your own device has that setting.

CSS Loader Generator: common questions

How do I show and hide the loader?

Insert the HTML when loading starts and remove it when it ends, using your own JavaScript or framework. The CSS animates the element for as long as it is on the page.

Why is the thickness limited?

Thickness can be at most a quarter of the size, because thicker rings and bars stop looking like the style. Size can be 16 to 400 px and one cycle 0.2 to 10 seconds.

Can I put several different loaders on one page?

Yes, but each copied snippet uses the class loader. Rename the class in one of them (in the HTML, the CSS selectors, the keyframes name and the custom property) so the two don’t override each other.

Why are the previews not moving?

Either you pressed Pause animations, or your device is set to reduce motion, in which case the page says so. The copied CSS still animates for visitors who haven’t turned that setting on.

Does the loader work in older browsers?

It uses CSS custom properties, calc() and transforms, which current browsers all support. Very old browsers that lack custom properties show the loader without animation.

Can I make other CSS effects here too?

This page only makes loaders. The CSS Background Pattern Generator and the Box Shadow Generator are among the other design tools.