25 CSS Spinners 01 / 25

Neon Arc CSS Spinner

A single glowing cyan arc rotates on a deep-dark background, with a luminous leading-edge dot that amplifies the neon effect via CSS drop-shadow filters.

Pure CSS MIT licensed
Live Demo Open in tab

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

Open in playground

The code

<div class="sp-01">
  <div class="sp-01__ring">
    <div class="sp-01__track"></div>
    <div class="sp-01__spinner">
      <div class="sp-01__arc"></div>
      <div class="sp-01__dot"></div>
    </div>
  </div>
</div>
.sp-01,.sp-01 *,.sp-01 *::before,.sp-01 *::after{box-sizing:border-box;margin:0;padding:0}
.sp-01{
  --bg:#0a0a0f;
  --arc:#00f5ff;
  --glow:rgba(0,245,255,0.4);
  --track:rgba(0,245,255,0.12);
  --size:72px;
  --thickness:4px;
  display:flex;
  align-items:center;
  justify-content:center;
  min-height:100vh;
  background:var(--bg);
  font-family:system-ui,sans-serif;
}
.sp-01__ring{
  position:relative;
  width:var(--size);
  height:var(--size);
}
.sp-01__track{
  position:absolute;
  inset:0;
  border-radius:50%;
  border:var(--thickness) solid var(--track);
}
/* The arc and dot-arm share one rotating parent so they move together */
.sp-01__spinner{
  position:absolute;
  inset:0;
  animation:sp-01-spin 1s cubic-bezier(0.6,0.2,0.4,0.8) infinite;
}
.sp-01__arc{
  position:absolute;
  inset:0;
  border-radius:50%;
  border:var(--thickness) solid transparent;
  border-top-color:var(--arc);
  border-right-color:var(--arc);
  filter:drop-shadow(0 0 8px var(--glow)) drop-shadow(0 0 16px var(--glow));
}
/* Leading-edge dot — a glowing tip at the LEADING END of the arc.
   The arc is built from border-top + border-right, so visually it
   spans ~135° (top-left corner) through 12 → 3 → ~225° (bottom-right
   corner). The END of border-right is at the bottom-right corner of
   the box (4:30 clock position), which is the LEADING tip during
   clockwise rotation.

   To position the dot at 4:30 on a 72×72 spinner: rotate 135° around
   the center via transform: rotate(135deg) translateY(-r), where r =
   (size/2 - thickness/2). Using a CSS custom property for r keeps
   this responsive to --size + --thickness changes.

   The dot is anchored at the spinner center (top:50%, left:50%) then
   rotated outward by 135° (= 4:30 clock direction = the leading-end
   of the arc), with translateY(-r) moving it to the arc's stroke
   midline radius. Sized 1.75× the arc thickness for a visible glowing
   tip without a chunky-bump look. */
.sp-01__dot{
  position:absolute;
  top:50%;
  left:50%;
  width:calc(var(--thickness) * 1.75);
  height:calc(var(--thickness) * 1.75);
  transform:translate(-50%, -50%) rotate(135deg) translateY(calc(var(--size) / -2 + var(--thickness) / 2));
  background:var(--arc);
  border-radius:50%;
  box-shadow:0 0 8px var(--arc),0 0 16px var(--glow);
}
@keyframes sp-01-spin{
  0%{transform:rotate(0deg)}
  100%{transform:rotate(360deg)}
}
@media (prefers-reduced-motion: reduce){
  .sp-01__spinner{animation:none}
}

How this works

The arc is a border-radius:50% element with two adjacent border sides coloured (border-top-color and border-right-color) and the remaining sides transparent. A filter:drop-shadow chain emits two layered glow halos, keeping the glowing effect entirely on the compositor without a box-shadow paint call.

The leading-edge dot is a separate small circle absolutely positioned at the top-center and shares the same @keyframes sp-01-spin animation so it tracks the arc tip precisely. A faint --track ring behind both layers provides the 360° guide rail visible at low opacity.

Customize

  • Change the glow colour by editing --arc and --glow custom properties on .sp-01 — both are cyan by default.
  • Adjust ring size with --size (default 72px) and stroke weight with --thickness (default 4px).
  • Swap to a slower, more elegant spin by changing the duration from 1s to 1.8s in sp-01-spin.
  • Remove the dot leading-edge for a minimal look by setting .sp-01__dot { display:none }.
  • Use cubic-bezier(0.4,0,0.6,1) instead of the current easing for a more mechanical feel.

Watch out for

  • filter:drop-shadow on a ring element can trigger GPU layer promotion — avoid stacking 20+ glowing rings on one page.
  • The arc tip dot uses translateX(-50%) combined with rotation, which can appear slightly offset in Safari below v15 due to transform-origin rounding.
  • On high-refresh displays the 1s spin feels slow; test at 0.7s for 120 Hz contexts.

Browser support

ChromeSafariFirefoxEdge
69+ 13+ 62+ 69+

drop-shadow filter is widely supported; no conic-gradient dependency.

Search CodeFronts

Loading…