Twisting puzzle cube
Pure CSSA 3×3×3 cube built as three layers that take turns twisting a quarter turn. Each layer is one flat box with the stickers painted on by gradients.
Three rings tilted into different planes, each with an electron going round inside its own plane.
Your edited version
transform, so a ring cannot both hold a tilt and animate a spin.rotateZ.rotateY then rotateX, never with rotateZ. A circle only cares which way its plane faces, and those two reach every direction, while rotateZ turns the square in the screen plane: 60° of it costs 37% more room for the same picture.--u, so the atom is the same share of a gallery card, the editor and a recording canvas. The rings are 200 of those units across.preserve-3dstatic tilt wrapper + spinning childown tilt and duration per ring<div class="scene">
<div class="atom">
<b></b>
<div class="plane"><u></u><div class="arm"><i></i></div></div>
<div class="plane"><u></u><div class="arm"><i></i></div></div>
<div class="plane"><u></u><div class="arm"><i></i></div></div>
</div>
</div>
.scene {
/* one base unit: every length below is a multiple of it, so the atom is the same share of a
card, the editor, a full screen and a recording canvas */
--u: 0.32vmin;
perspective: calc(800 * var(--u));
}
.atom {
position: relative;
width: calc(200 * var(--u));
height: calc(200 * var(--u));
transform-style: preserve-3d;
}
.atom b {
position: absolute;
inset: 40%;
border-radius: 50%;
background: radial-gradient(circle at 35% 35%, #fff, #8b6cff 60%);
box-shadow: 0 0 calc(24 * var(--u)) #8b6cff;
}
.plane {
position: absolute;
inset: 0;
transform-style: preserve-3d;
}
/* the same three planes as rotateZ(0 / ±60deg) rotateX(72deg), said with rotateY instead: each
ring faces exactly the same way, but no square is turned in the screen plane */
.plane:nth-of-type(1) { transform: rotateX(72deg); color: #2ee6d6; }
.plane:nth-of-type(2) { transform: rotateY(69.44deg) rotateX(28.39deg); color: #ff4d9d; }
.plane:nth-of-type(3) { transform: rotateY(-69.44deg) rotateX(28.39deg); color: #ffb547; }
/* the ring: drawn, and never turned — so its square box is only ever as wide as the circle in it */
.plane u {
position: absolute;
inset: 0;
border: calc(2 * var(--u)) solid currentColor;
border-radius: 50%;
}
/* the arm: turned, and draws nothing — it exists only to carry the electron round */
.arm {
position: absolute;
inset: 0;
animation: orbit-spin 3s linear infinite;
}
.plane:nth-of-type(2) .arm { animation-duration: 3.7s; }
.plane:nth-of-type(3) .arm { animation-duration: 4.4s; }
.arm i {
position: absolute;
top: calc(-7 * var(--u));
left: calc(50% - 6 * var(--u));
width: calc(12 * var(--u));
height: calc(12 * var(--u));
border-radius: 50%;
background: currentColor;
box-shadow: 0 0 calc(12 * var(--u)) currentColor;
}
@keyframes orbit-spin {
to { transform: rotateZ(360deg); }
}