Loaders & patterns
Gyroscope
Pure CSSThree nested rings, each spinning on a different axis — the rotations compound.
The classic square loader: half a turn on X, then half a turn on Y.
Your edited version
perspective() function goes inside the transform itself.perspective.perspective() inside transformmulti-step @keyframesno wrapper needed<div class="loader"></div>
.loader {
width: 90px;
height: 90px;
border-radius: 12px;
background: linear-gradient(135deg, #2ee6d6, #8b6cff);
box-shadow: 0 0 30px rgb(139 108 255 / 0.6);
animation: flip 1.8s ease-in-out infinite;
}
@keyframes flip {
0% { transform: perspective(260px) rotateX(0deg) rotateY(0deg); }
50% { transform: perspective(260px) rotateX(-180deg) rotateY(0deg); }
100% { transform: perspective(260px) rotateX(-180deg) rotateY(-180deg); }
}
.d-flipper {
width: 76px;
height: 76px;
border-radius: 10px;
background: linear-gradient(135deg, var(--accent-2), var(--accent));
box-shadow: 0 0 30px color-mix(in srgb, var(--accent) 60%, transparent);
animation: d-flipper 1.8s ease-in-out infinite;
}
// perspective() INSIDE the transform: a self-contained 3D element, no parent needed.
@keyframes d-flipper {
0% {
transform: perspective(240px) rotateX(0deg) rotateY(0deg);
}
50% {
transform: perspective(240px) rotateX(-180deg) rotateY(0deg);
}
100% {
transform: perspective(240px) rotateX(-180deg) rotateY(-180deg);
}
}