20 CSS Loaders 14 / 20
CSS Morphing Square Loader
Four square-based CSS loaders — a border-radius morph, a corner-orbit rotation, a four-square chase path, and a perspective 3D flip — demonstrating CSS shape-shifting and spatial transforms.
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-14">
<div class="ld-14__stage">
<div class="ld-14__cell"><div class="ld-14__morph"></div><span class="ld-14__label">Morphing</span></div>
<div class="ld-14__cell"><div class="ld-14__sq-orbit"><span></span><span></span><span></span><span></span></div><span class="ld-14__label">Corner Orbit</span></div>
<div class="ld-14__cell"><div class="ld-14__chase-sq"><span></span><span></span><span></span><span></span></div><span class="ld-14__label">Chase Squares</span></div>
<div class="ld-14__cell"><div class="ld-14__sq-spin"></div><span class="ld-14__label">3D Flip</span></div>
</div> <div class="ld-14">
<div class="ld-14__stage">
<div class="ld-14__cell"><div class="ld-14__morph"></div><span class="ld-14__label">Morphing</span></div>
<div class="ld-14__cell"><div class="ld-14__sq-orbit"><span></span><span></span><span></span><span></span></div><span class="ld-14__label">Corner Orbit</span></div>
<div class="ld-14__cell"><div class="ld-14__chase-sq"><span></span><span></span><span></span><span></span></div><span class="ld-14__label">Chase Squares</span></div>
<div class="ld-14__cell"><div class="ld-14__sq-spin"></div><span class="ld-14__label">3D Flip</span></div>
</div>.ld-14,.ld-14 *,.ld-14 *::before,.ld-14 *::after{box-sizing:border-box;margin:0;padding:0}
.ld-14{
--bg:#1a0533;--c1:#d63af9;--c2:#7c3aed;--c3:#ec4899;--c4:#f59e0b;
background:var(--bg);display:flex;align-items:center;justify-content:center;min-height:100vh;font-family:'Segoe UI',sans-serif;
}
.ld-14__stage{display:flex;gap:70px;flex-wrap:wrap;justify-content:center;padding:40px;align-items:center}
.ld-14__cell{display:flex;flex-direction:column;align-items:center;gap:20px}
.ld-14__label{color:rgba(255,255,255,.35);font-size:11px;letter-spacing:1.5px;text-transform:uppercase}
/* Morph shape */
.ld-14__morph{width:60px;height:60px;background:linear-gradient(135deg,var(--c1),var(--c2));animation:ld-14-morph 3s ease-in-out infinite}
@keyframes ld-14-morph{0%{border-radius:4px;transform:rotate(0)}25%{border-radius:50%;transform:rotate(90deg)}50%{border-radius:4px;transform:rotate(180deg)}75%{border-radius:50% 4px;transform:rotate(270deg)}100%{border-radius:4px;transform:rotate(360deg)}}
/* Square orbit */
.ld-14__sq-orbit{width:60px;height:60px;position:relative;animation:ld-14-orbit 2s linear infinite}
.ld-14__sq-orbit span{position:absolute;width:14px;height:14px;background:var(--c3);border-radius:2px}
.ld-14__sq-orbit span:nth-child(1){top:0;left:0}
.ld-14__sq-orbit span:nth-child(2){top:0;right:0;background:var(--c1);animation:ld-14-sq-pulse .5s ease-in-out infinite alternate}
.ld-14__sq-orbit span:nth-child(3){bottom:0;right:0;background:var(--c4)}
.ld-14__sq-orbit span:nth-child(4){bottom:0;left:0;background:var(--c2)}
@keyframes ld-14-orbit{to{transform:rotate(360deg)}}
@keyframes ld-14-sq-pulse{to{border-radius:50%}}
/* Chase squares */
.ld-14__chase-sq{width:60px;height:60px;position:relative}
.ld-14__chase-sq span{position:absolute;width:20px;height:20px;border-radius:3px;animation:ld-14-chase-sq 1.5s ease-in-out infinite}
.ld-14__chase-sq span:nth-child(1){background:var(--c1);animation-delay:0s}
.ld-14__chase-sq span:nth-child(2){background:var(--c2);animation-delay:.375s}
.ld-14__chase-sq span:nth-child(3){background:var(--c3);animation-delay:.75s}
.ld-14__chase-sq span:nth-child(4){background:var(--c4);animation-delay:1.125s}
@keyframes ld-14-chase-sq{
0%{transform:translate(0,0)}
25%{transform:translate(40px,0)}
50%{transform:translate(40px,40px)}
75%{transform:translate(0,40px)}
100%{transform:translate(0,0)}
}
/* Spinner square */
.ld-14__sq-spin{width:44px;height:44px;border:4px solid var(--c4);border-radius:4px;animation:ld-14-sq-spin 1.2s ease-in-out infinite}
@keyframes ld-14-sq-spin{0%{transform:perspective(120px) rotateX(0) rotateY(0)}50%{transform:perspective(120px) rotateX(-180deg) rotateY(0)}100%{transform:perspective(120px) rotateX(-180deg) rotateY(-180deg)}}
@media(prefers-reduced-motion:reduce){
.ld-14__morph,.ld-14__sq-orbit,.ld-14__sq-orbit span,.ld-14__chase-sq span,.ld-14__sq-spin{animation:none}
} .ld-14,.ld-14 *,.ld-14 *::before,.ld-14 *::after{box-sizing:border-box;margin:0;padding:0}
.ld-14{
--bg:#1a0533;--c1:#d63af9;--c2:#7c3aed;--c3:#ec4899;--c4:#f59e0b;
background:var(--bg);display:flex;align-items:center;justify-content:center;min-height:100vh;font-family:'Segoe UI',sans-serif;
}
.ld-14__stage{display:flex;gap:70px;flex-wrap:wrap;justify-content:center;padding:40px;align-items:center}
.ld-14__cell{display:flex;flex-direction:column;align-items:center;gap:20px}
.ld-14__label{color:rgba(255,255,255,.35);font-size:11px;letter-spacing:1.5px;text-transform:uppercase}
/* Morph shape */
.ld-14__morph{width:60px;height:60px;background:linear-gradient(135deg,var(--c1),var(--c2));animation:ld-14-morph 3s ease-in-out infinite}
@keyframes ld-14-morph{0%{border-radius:4px;transform:rotate(0)}25%{border-radius:50%;transform:rotate(90deg)}50%{border-radius:4px;transform:rotate(180deg)}75%{border-radius:50% 4px;transform:rotate(270deg)}100%{border-radius:4px;transform:rotate(360deg)}}
/* Square orbit */
.ld-14__sq-orbit{width:60px;height:60px;position:relative;animation:ld-14-orbit 2s linear infinite}
.ld-14__sq-orbit span{position:absolute;width:14px;height:14px;background:var(--c3);border-radius:2px}
.ld-14__sq-orbit span:nth-child(1){top:0;left:0}
.ld-14__sq-orbit span:nth-child(2){top:0;right:0;background:var(--c1);animation:ld-14-sq-pulse .5s ease-in-out infinite alternate}
.ld-14__sq-orbit span:nth-child(3){bottom:0;right:0;background:var(--c4)}
.ld-14__sq-orbit span:nth-child(4){bottom:0;left:0;background:var(--c2)}
@keyframes ld-14-orbit{to{transform:rotate(360deg)}}
@keyframes ld-14-sq-pulse{to{border-radius:50%}}
/* Chase squares */
.ld-14__chase-sq{width:60px;height:60px;position:relative}
.ld-14__chase-sq span{position:absolute;width:20px;height:20px;border-radius:3px;animation:ld-14-chase-sq 1.5s ease-in-out infinite}
.ld-14__chase-sq span:nth-child(1){background:var(--c1);animation-delay:0s}
.ld-14__chase-sq span:nth-child(2){background:var(--c2);animation-delay:.375s}
.ld-14__chase-sq span:nth-child(3){background:var(--c3);animation-delay:.75s}
.ld-14__chase-sq span:nth-child(4){background:var(--c4);animation-delay:1.125s}
@keyframes ld-14-chase-sq{
0%{transform:translate(0,0)}
25%{transform:translate(40px,0)}
50%{transform:translate(40px,40px)}
75%{transform:translate(0,40px)}
100%{transform:translate(0,0)}
}
/* Spinner square */
.ld-14__sq-spin{width:44px;height:44px;border:4px solid var(--c4);border-radius:4px;animation:ld-14-sq-spin 1.2s ease-in-out infinite}
@keyframes ld-14-sq-spin{0%{transform:perspective(120px) rotateX(0) rotateY(0)}50%{transform:perspective(120px) rotateX(-180deg) rotateY(0)}100%{transform:perspective(120px) rotateX(-180deg) rotateY(-180deg)}}
@media(prefers-reduced-motion:reduce){
.ld-14__morph,.ld-14__sq-orbit,.ld-14__sq-orbit span,.ld-14__chase-sq span,.ld-14__sq-spin{animation:none}
}How this works
The morphing square cycles border-radius through four steps — 4px (square), 50% (circle), 4px (square), 50% 4px (teardrop) — while simultaneously rotating 360deg via a compound transform, so both the shape and orientation change together. This requires only one element and zero children. The corner orbit places four squares at the corners of a parent container and spins the parent — the squares maintain their corner positions while orbiting the centre.
The chase path animation uses four squares with the same keyframe but offset delays of 0s, 0.375s, 0.75s, 1.125s — each walks a square path via four translate keyframe steps (0,0 → 40,0 → 40,40 → 0,40 → 0,0), so they walk in single file. The 3D flip uses perspective(120px) in the transform value combined with sequential rotateX(180deg) and rotateY(180deg) to produce a card-tumble effect without a full 3D scene.
Customize
- Adjust morph timing by changing the
animation-timing-function—ease-in-outgives smooth blob transitions;steps(4)gives a hard digital snap between shapes. - Change the chase path size by editing the translate values —
40pxcorresponds to parent width minus square size; scale both together for different container sizes. - Add colour cycling to the morph shape by including a
backgroundkeyframe step that transitions between gradient stops in sync with the shape change. - Adjust corner orbit speed per-corner by adding individual
animation-durationoverrides on each span — slightly different speeds create an organic asymmetric rotation. - Increase the 3D flip depth by increasing the
perspectivevalue in the transform from120pxto200px— higher values flatten the perspective; lower values are more dramatic.
Watch out for
- The four-square chase requires that the parent container has an explicit
widthandheightmatching the translate range — a60pxcontainer with40pxtranslate values leaves each square at the corner correctly. - The morph animation compound transform (
border-radius+rotate) requires both properties in the same keyframe; splitting them into separate animations causes them to use independent timing curves. - The perspective-flip
perspective(120px) rotateX/Yapproach creates a local perspective per element — combining multiple 3D-flipping squares in a gallery needs a shared parent perspective to prevent perspective collisions.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 49+ | 9+ | 44+ | 49+ |
All transform techniques are universally supported; CSS perspective-in-transform works in all modern browsers.