20 CSS Loaders01 / 20

Pure CSSMIT licensed

CSS Spinning Ring Loader

Six ring-based CSS spinners — classic, double, triple nested, dashed, gradient conic, and pulse ring — demonstrating the full spectrum of border and conic-gradient spin techniques.

Published

Live Demo
Try it

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

The code

<div class="ld-01">
  <div class="ld-01__stage">
    <div class="ld-01__cell"><div class="ld-01__ring"></div><span class="ld-01__label">Classic Ring</span></div>
    <div class="ld-01__cell"><div class="ld-01__double"></div><span class="ld-01__label">Double Ring</span></div>
    <div class="ld-01__cell"><div class="ld-01__triple"><span></span><span></span><span></span></div><span class="ld-01__label">Triple Ring</span></div>
    <div class="ld-01__cell"><div class="ld-01__dashed"></div><span class="ld-01__label">Dashed Ring</span></div>
    <div class="ld-01__cell"><div class="ld-01__gradient"></div><span class="ld-01__label">Gradient Ring</span></div>
    <div class="ld-01__cell"><div class="ld-01__pulse-ring"></div><span class="ld-01__label">Pulse Ring</span></div>
  </div>
.ld-01,
.ld-01 *,
.ld-01 *::before,
.ld-01 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.ld-01 {
  --bg: #0a0a0f;
  --accent: #6c63ff;
  --accent2: #ff6584;
  --accent3: #43e97b;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  font-family: 'Segoe UI',sans-serif;
}

.ld-01__stage {
  display: flex;
  gap: 48px;
  flex-wrap: wrap;
  justify-content: center;
  padding: 40px;
}

.ld-01__cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.ld-01__label {
  color: rgba(255,255,255,.5);
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}
/* Classic Ring */

.ld-01__ring {
  width: 56px;
  height: 56px;
  border: 4px solid rgba(108,99,255,.2);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: ld-01-spin 1s linear infinite;
}

@keyframes ld-01-spin {
  to {
    transform: rotate(360deg);
  }
}
/* Double Ring */

.ld-01__double {
  width: 56px;
  height: 56px;
  border: 4px solid transparent;
  border-top-color: var(--accent);
  border-bottom-color: var(--accent2);
  border-radius: 50%;
  animation: ld-01-spin 1.2s linear infinite;
}
/* Triple Ring */

.ld-01__triple {
  width: 60px;
  height: 60px;
  position: relative;
}

.ld-01__triple span {
  position: absolute;
  border-radius: 50%;
  border: 3px solid transparent;
  animation: ld-01-spin linear infinite;
}

.ld-01__triple span:nth-child(1) {
  inset: 0;
  border-top-color: var(--accent);
  animation-duration: .9s;
}

.ld-01__triple span:nth-child(2) {
  inset: 8px;
  border-top-color: var(--accent2);
  animation-duration: 1.3s;
  animation-direction: reverse;
}

.ld-01__triple span:nth-child(3) {
  inset: 16px;
  border-top-color: var(--accent3);
  animation-duration: 1.7s;
}
/* Dashed Ring */

.ld-01__dashed {
  width: 56px;
  height: 56px;
  border: 4px dashed var(--accent);
  border-radius: 50%;
  animation: ld-01-spin 2s linear infinite;
  opacity: .8;
}
/* Gradient Ring */

.ld-01__gradient {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: conic-gradient(var(--accent),var(--accent2),var(--accent3),var(--accent));
  animation: ld-01-spin 1s linear infinite;
  -webkit-mask: radial-gradient(farthest-side,#0000 calc(100% - 6px),#000 0);
}
/* Pulsing Ring */

.ld-01__pulse-ring {
  width: 56px;
  height: 56px;
  border: 4px solid var(--accent);
  border-radius: 50%;
  animation: ld-01-pulse-ring 1.5s ease-out infinite;
}

@keyframes ld-01-pulse-ring {
  0% {
    transform: scale(.8);
    opacity: 1;
  }

  100% {
    transform: scale(1.5);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ld-01__ring,
    .ld-01__double,
    .ld-01__triple span,
    .ld-01__dashed,
    .ld-01__gradient,
    .ld-01__pulse-ring {
    animation: none;
  }
}
Paste this into ChatGPT, Claude, Cursor, or any coding assistant. The block below is pre-framed with everything the AI needs to integrate this demo into your project — markup, styles, scoping notes, and the source URL. Hit Copy and paste straight into your chat.
Here's a working CSS Loader from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: CSS Spinning Ring Loader
Source: https://codefronts.com/motion/css-loader-designs/css-spinning-ring-loader/

Six ring-based CSS spinners — classic, double, triple nested, dashed, gradient conic, and pulse ring — demonstrating the full spectrum of border and conic-gradient spin techniques.
## HTML
```html
<div class="ld-01">
  <div class="ld-01__stage">
    <div class="ld-01__cell"><div class="ld-01__ring"></div><span class="ld-01__label">Classic Ring</span></div>
    <div class="ld-01__cell"><div class="ld-01__double"></div><span class="ld-01__label">Double Ring</span></div>
    <div class="ld-01__cell"><div class="ld-01__triple"><span></span><span></span><span></span></div><span class="ld-01__label">Triple Ring</span></div>
    <div class="ld-01__cell"><div class="ld-01__dashed"></div><span class="ld-01__label">Dashed Ring</span></div>
    <div class="ld-01__cell"><div class="ld-01__gradient"></div><span class="ld-01__label">Gradient Ring</span></div>
    <div class="ld-01__cell"><div class="ld-01__pulse-ring"></div><span class="ld-01__label">Pulse Ring</span></div>
  </div>
```
## CSS
```css
.ld-01,
.ld-01 *,
.ld-01 *::before,
.ld-01 *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.ld-01 {
  --bg: #0a0a0f;
  --accent: #6c63ff;
  --accent2: #ff6584;
  --accent3: #43e97b;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  font-family: 'Segoe UI',sans-serif;
}

.ld-01__stage {
  display: flex;
  gap: 48px;
  flex-wrap: wrap;
  justify-content: center;
  padding: 40px;
}

.ld-01__cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.ld-01__label {
  color: rgba(255,255,255,.5);
  font-size: 11px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
}
/* Classic Ring */

.ld-01__ring {
  width: 56px;
  height: 56px;
  border: 4px solid rgba(108,99,255,.2);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: ld-01-spin 1s linear infinite;
}

@keyframes ld-01-spin {
  to {
    transform: rotate(360deg);
  }
}
/* Double Ring */

.ld-01__double {
  width: 56px;
  height: 56px;
  border: 4px solid transparent;
  border-top-color: var(--accent);
  border-bottom-color: var(--accent2);
  border-radius: 50%;
  animation: ld-01-spin 1.2s linear infinite;
}
/* Triple Ring */

.ld-01__triple {
  width: 60px;
  height: 60px;
  position: relative;
}

.ld-01__triple span {
  position: absolute;
  border-radius: 50%;
  border: 3px solid transparent;
  animation: ld-01-spin linear infinite;
}

.ld-01__triple span:nth-child(1) {
  inset: 0;
  border-top-color: var(--accent);
  animation-duration: .9s;
}

.ld-01__triple span:nth-child(2) {
  inset: 8px;
  border-top-color: var(--accent2);
  animation-duration: 1.3s;
  animation-direction: reverse;
}

.ld-01__triple span:nth-child(3) {
  inset: 16px;
  border-top-color: var(--accent3);
  animation-duration: 1.7s;
}
/* Dashed Ring */

.ld-01__dashed {
  width: 56px;
  height: 56px;
  border: 4px dashed var(--accent);
  border-radius: 50%;
  animation: ld-01-spin 2s linear infinite;
  opacity: .8;
}
/* Gradient Ring */

.ld-01__gradient {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: conic-gradient(var(--accent),var(--accent2),var(--accent3),var(--accent));
  animation: ld-01-spin 1s linear infinite;
  -webkit-mask: radial-gradient(farthest-side,#0000 calc(100% - 6px),#000 0);
}
/* Pulsing Ring */

.ld-01__pulse-ring {
  width: 56px;
  height: 56px;
  border: 4px solid var(--accent);
  border-radius: 50%;
  animation: ld-01-pulse-ring 1.5s ease-out infinite;
}

@keyframes ld-01-pulse-ring {
  0% {
    transform: scale(.8);
    opacity: 1;
  }

  100% {
    transform: scale(1.5);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ld-01__ring,
    .ld-01__double,
    .ld-01__triple span,
    .ld-01__dashed,
    .ld-01__gradient,
    .ld-01__pulse-ring {
    animation: none;
  }
}
```

How this works

The classic ring spins a single-sided border-top-color on a transparent ring using a linear rotate(360deg) keyframe. The gradient ring replaces the border entirely with a conic-gradient masked by radial-gradient using -webkit-mask to cut out the inner circle, producing a smooth colour-wheel sweep. The triple variant stacks three absolutely positioned elements with different animation-duration and animation-direction:reverse values to create counter-rotating layers.

The pulse ring uses scale and opacity together in a single keyframe — growing from 0.8 to 1.5 while fading to zero — to create an outward sonar effect with zero DOM overhead. All variants animate only transform and opacity to stay on the GPU compositor layer.

Make it yours

  • Change ring thickness by editing border-width on .ld-01__ring — try 6px for a bolder look or 2px for a hairline.
  • Adjust spinner speed by multiplying each animation-duration — lower values like 0.6s feel urgent while 2s is calm and meditative.
  • Swap the colour palette by editing --accent, --accent2, and --accent3 CSS custom properties at the .ld-01 root.
  • Increase the conic gradient tail by changing the transparent stop in conic-gradient(var(--accent),var(--accent2),var(--accent3),var(--accent)) — add a transparent 0% before the first colour for a sharp start.
  • Use animation-play-state: paused to freeze spinners off-screen, reducing CPU/GPU load for multiple instances on one page.

Gotchas — read before shipping

  • The -webkit-mask radial gradient approach for the gradient ring fails in IE11 and Edge < 79 — provide a plain border-top spinner as fallback.
  • Stacking triple rings causes heavy composite layers on low-end devices; test on throttled mobile before using more than two overlapping animations.
  • The pulse ring scale + opacity loop can appear to stutter at exactly 1x devicePixelRatio if will-change: transform is not set — add it if you see jank.

Browser support

ChromeSafariFirefoxEdge
69+12.1+83+69+

Conic-gradient mask requires Safari 15.4+ for full support; older Safari renders a solid disk instead.

Techniques used in this demo

Search CodeFronts

Loading…