3D equalizer
Pure CSSSeven real cuboids bouncing like an audio meter. Walls are squashed with scaleY and each lid rides down by the same amount, so nothing but transforms ever changes.
Three nested rings, each spinning on a single axis — the rotations compound.
Your edited version
transform-style: preserve-3d or the chain flattens there.--u, tied to the canvas, and each ring inside is 84% of the one around it, so the whole gyroscope is the same share of a gallery card, the editor and a recording canvas.nested preserve-3done axis per leveldifferent durations<div class="scene">
<div class="gyro">
<div>
<div>
<b><i style="--i:0"></i><i style="--i:1"></i><i style="--i:2"></i><i></i></b>
</div>
</div>
</div>
</div>
.scene {
/* one base unit: every length below is a multiple of it, so the gyroscope is the same share of
a gallery card, the editor, a full screen and a recording canvas */
--u: 0.24vmin;
perspective: calc(800 * var(--u));
}
.gyro,
.gyro div {
box-sizing: content-box; /* each ring is 84% of the inside of the one round it: by design, on any page */
display: grid;
place-items: center;
border: calc(4 * var(--u)) solid #8b6cff;
border-radius: 50%;
transform-style: preserve-3d;
}
.gyro {
width: calc(220 * var(--u));
height: calc(220 * var(--u));
animation: gyro-x 6s linear infinite;
}
.gyro div {
width: 84%;
height: 84%;
}
.gyro > div {
border-color: #2ee6d6;
animation: gyro-y 4s linear infinite;
}
.gyro > div > div {
border-color: #ff4d9d;
animation: gyro-x 2.6s linear infinite reverse;
}
/* the core: a flat disc seen edge-on draws nothing, so it is four glowing discs crossed through
one centre, three turned round the vertical and one laid flat. Whichever way the rings turn
it, at least one of them faces you. */
.gyro b {
position: relative;
width: 34%;
height: 34%;
transform-style: preserve-3d;
}
.gyro b i {
position: absolute;
inset: 0;
border-radius: 50%;
background: radial-gradient(circle, #fff, #ffb547 50%, rgb(255 181 71 / 0.35) 72%, rgb(255 181 71 / 0) 100%);
transform: rotateY(calc(var(--i) * 60deg));
}
.gyro b i:last-child {
transform: rotateX(90deg);
}
@keyframes gyro-x { to { transform: rotateX(360deg); } }
@keyframes gyro-y { to { transform: rotateY(360deg); } }