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.
A 4×4 grid of two-sided tiles flipping in a diagonal wave.
Your edited version
::before and ::after, back to back, both with backface-visibility: hidden.animation-delay = (row + column) × step. Each tile sets its --d, row + column, in its style.--u, tied to the canvas: a tile is 48 units square, 8 apart, and sinks 14 as it turns, so the wave is the same share of a gallery card, the editor and a recording canvas.backface-visibilitydelay = (row + column) × step--d per tile in its style<div class="scene">
<div class="tiles">
<i style="--d:0"></i><i style="--d:1"></i><i style="--d:2"></i><i style="--d:3"></i>
<i style="--d:1"></i><i style="--d:2"></i><i style="--d:3"></i><i style="--d:4"></i>
<i style="--d:2"></i><i style="--d:3"></i><i style="--d:4"></i><i style="--d:5"></i>
<i style="--d:3"></i><i style="--d:4"></i><i style="--d:5"></i><i style="--d:6"></i>
</div>
</div>
.scene {
/* one base unit: every length below is a multiple of it, so the wave is the same share of a
gallery card, the editor, a full screen and a recording canvas */
--u: 0.3vmin;
perspective: calc(800 * var(--u));
}
.tiles {
display: grid;
grid-template-columns: repeat(4, calc(48 * var(--u)));
gap: calc(8 * var(--u));
transform-style: preserve-3d;
transform: rotateX(38deg) rotateZ(-8deg);
}
.tiles i {
position: relative;
height: calc(48 * var(--u));
transform-style: preserve-3d;
animation: tile-flip 3.2s ease-in-out infinite;
animation-delay: calc(var(--d) * 0.13s); /* --d = row + column */
}
.tiles i::before,
.tiles i::after {
content: '';
position: absolute;
inset: 0;
border-radius: calc(8 * var(--u));
backface-visibility: hidden;
}
.tiles i::before { background: #8b6cff; }
.tiles i::after { background: #2ee6d6; transform: rotateY(180deg); }
@keyframes tile-flip {
0%, 15% { transform: rotateY(0deg); }
45%, 65% { transform: rotateY(180deg) translateZ(calc(-14 * var(--u))); }
95%, 100% { transform: rotateY(360deg); }
}