CSS Loaders
Four pure-CSS loading indicators: a ring spinner, bouncing dots, an equaliser and a pulsing circle. Copy the one you need.
The code
Plain HTML and CSS with no dependencies. Copy a single file, or choose "Full file" for a complete page you can save as index.html and open in a browser.
<div class="loaders">
<figure>
<div class="spinner" role="status" aria-label="Loading"></div>
<figcaption>Spinner</figcaption>
</figure>
<figure>
<div class="dots" role="status" aria-label="Loading"><i></i><i></i><i></i></div>
<figcaption>Dots</figcaption>
</figure>
<figure>
<div class="bars" role="status" aria-label="Loading"><i></i><i></i><i></i><i></i></div>
<figcaption>Bars</figcaption>
</figure>
<figure>
<div class="pulse" role="status" aria-label="Loading"></div>
<figcaption>Pulse</figcaption>
</figure>
</div>The AI prompt
Paste this into an AI coding tool to generate the same component, then ask it to adapt the colours, text or framework to your project.
Create a set of four pure-CSS loading indicators in one HTML file (no JavaScript, no images). 1. Ring spinner: a 40px circle with a 4px light grey border and an indigo (#2506ad) top border, rotating 360 degrees every 0.8s. 2. Bouncing dots: three 10px indigo dots that move up 12px and fade, alternating, with staggered delays of 0.15s. 3. Equaliser bars: four 6px wide orange (#ff7b00) bars that scale vertically between 0.3 and 1, with staggered delays of 0.1s. 4. Pulse: a 40px indigo circle that scales from 0.4 to 1.1 while fading out, repeating every 1.2s. Present each inside a 130px white tile with a 1px border, 16px radius and a small grey caption, arranged in a centred, wrapping flex row on a light grey page. Add role="status" and aria-label="Loading" to each loader. Slow the animations under prefers-reduced-motion. Return one HTML file with a <style> block.
How to build it, step by step
- 1
Spinner: draw a circle with a border, colour only one side with border-top-color, and rotate it with a linear infinite animation.
- 2
Dots: animate each dot with the same keyframes and stagger them using animation-delay.
- 3
Bars: animate transform: scaleY() rather than height. Transforms are handled by the GPU and do not trigger layout.
- 4
Pulse: combine scale and opacity so the circle grows and fades at the same time.
- 5
Add role='status' and an aria-label so assistive technology announces that content is loading.
Customisation tips
- Show loaders only after about 300ms; flashing a spinner for instant responses feels slower.
- For content that has a known layout, prefer skeleton placeholders over spinners.
- Use currentColor instead of fixed colours so a loader inherits the text colour of its container.