Orbit Dots
A classic spinning orbit, rebuilt in pure CSS. Two-dot and three-dot versions, themable via CSS variables.
Loading…
Loading…
Variants
Loading…
Loading…
Use this on your site (self-host)
- Create
/assets/preloaders/
and saveorbit-dots.css
there. - Add the HTML snippet where you want the spinner.
- Tweak
--size
,--speed
, colors (--dot1
–--dot3
,--ring
), and variants (--ringWidth
,--tilt
,--persp
).
HTML
<link rel="stylesheet" href="/assets/preloaders/orbit-dots.css">
<!-- Two-dot (default circle) -->
<div class="rc-orbit rc-orbit--2" role="status" aria-label="Loading"
style="--size:88px;--speed:1400ms">
<span class="sr-only">Loading…</span>
<span class="ring" aria-hidden="true"></span>
<span class="dot d1" aria-hidden="true"></span>
<span class="dot d2" aria-hidden="true"></span>
</div>
<!-- Three-dot with thicker ring -->
<div class="rc-orbit rc-orbit--3" role="status" aria-label="Loading"
style="--size:88px;--speed:1500ms;--ringWidth:3px;--ring:rgba(255,255,255,.25)">
<span class="sr-only">Loading…</span>
<span class="ring" aria-hidden="true"></span>
<span class="dot d1" aria-hidden="true"></span>
<span class="dot d2" aria-hidden="true"></span>
<span class="dot d3" aria-hidden="true"></span>
</div>
<!-- Elliptical / 3D tilt -->
<div class="rc-orbit rc-orbit--2" role="status" aria-label="Loading"
style="--size:88px;--speed:1400ms;--tilt:30deg;--persp:700px">
<span class="sr-only">Loading…</span>
<span class="ring" aria-hidden="true"></span>
<span class="dot d1" aria-hidden="true"></span>
<span class="dot d2" aria-hidden="true"></span>
</div>
CSS
/* RetroCrave — Orbit Dots (CSS-only) */
.rc-orbit{
--size: 96px;
--speed: 1400ms;
--ring: rgba(255,255,255,.18);
--ringWidth: 1px; /* ring thickness */
--dot1: #5ef1ff;
--dot2: #ff6bd6;
--dot3: #ffe66b;
--dotSize: 12px;
--r: calc(var(--size)/2 - var(--dotSize)/2);
/* 3D tilt */
--persp: 600px;
--tilt: 0deg; /* set to e.g. 30deg for ellipse */
position:relative; width:var(--size); height:var(--size);
display:inline-grid; place-items:center;
transform-style: preserve-3d;
transform: perspective(var(--persp)) rotateX(var(--tilt));
transform-origin: center;
}
.rc-orbit .ring{
position:absolute; inset:0; border-radius:50%;
border: var(--ringWidth) solid var(--ring);
}
.rc-orbit .dot{
position:absolute; left:50%; top:50%;
width:var(--dotSize); height:var(--dotSize); border-radius:50%;
transform: rotate(0deg) translate(var(--r)) rotate(0deg);
will-change: transform;
}
@keyframes rc-spin{ to{ transform: rotate(360deg) translate(var(--r)) rotate(-360deg); } }
/* 2-dot */
.rc-orbit--2 .d1{ background:var(--dot1); animation:rc-spin var(--speed) linear infinite; }
.rc-orbit--2 .d2{ background:var(--dot2); animation:rc-spin var(--speed) linear infinite; animation-delay: calc(var(--speed) / -2); }
/* 3-dot */
.rc-orbit--3 .d1{ background:var(--dot1); animation:rc-spin var(--speed) linear infinite; }
.rc-orbit--3 .d2{ background:var(--dot2); animation:rc-spin var(--speed) linear infinite; animation-delay: calc(var(--speed) / -3); }
.rc-orbit--3 .d3{ background:var(--dot3); animation:rc-spin var(--speed) linear infinite; animation-delay: calc(var(--speed) * -2 / 3); }
/* Reduced motion */
@media (prefers-reduced-motion: reduce){
.rc-orbit .dot{ animation: none !important; transform: translate(-50%,-50%) !important; }
}
/* A11y helper */
.sr-only{
position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
clip:rect(0,0,0,0);white-space:nowrap;border:0;
}
- On light backgrounds, set
--ring: rgba(0,0,0,.2)
. - Try
--ringWidth: 2px–4px
and--tilt: 20–35deg
for a nice ellipse.