HTML 12 lines
<div class="scene">
<div class="chart">
<!-- --hn = full height in units of --u, as a plain number -->
<!-- --delay staggers the bars 0.35s apart, all 0.75s in: the first frame, which a paused
card shows, is the chart grown, not five stubs -->
<div class="bar" style="--hn:70; --hue:262; --delay:-0.75s"><i></i><i></i><i></i></div>
<div class="bar" style="--hn:110; --hue:285; --delay:-1.1s"><i></i><i></i><i></i></div>
<div class="bar" style="--hn:50; --hue:320; --delay:-1.45s"><i></i><i></i><i></i></div>
<div class="bar" style="--hn:140; --hue:175; --delay:-1.8s"><i></i><i></i><i></i></div>
<div class="bar" style="--hn:90; --hue:40; --delay:-2.15s"><i></i><i></i><i></i></div>
</div>
</div>
CSS 73 lines
.scene {
/* one base unit: every length below is a multiple of it, so the chart is the same share of a
gallery card, the editor, a full screen and a recording canvas */
--u: 0.38vmin;
perspective: calc(900 * var(--u));
}
.chart {
--w: calc(30 * var(--u));
display: flex;
align-items: flex-end;
gap: calc(18 * var(--u));
height: calc(150 * var(--u));
transform-style: preserve-3d;
/* the chart is seen from above, so what it draws hangs below its layout box: the lift puts
the drawing, not the box, in the middle */
transform: translate(calc(-5 * var(--u)), calc(-20 * var(--u))) rotateX(-22deg) rotateY(-32deg);
}
.bar {
--h: calc(var(--hn) * var(--u)); /* full height */
--k: calc(14 / var(--hn)); /* scale of the shortest state: 14 units */
position: relative;
width: var(--w);
height: var(--h); /* the box itself never changes size */
transform-style: preserve-3d;
}
.bar i {
position: absolute;
top: 0;
left: 0;
width: var(--w);
height: 100%;
transform-origin: bottom center;
animation: 1.8s ease-in-out var(--delay) infinite alternate;
}
/* front */
.bar i:nth-child(1) {
background: hsl(var(--hue) 80% 60%);
transform: translateZ(calc(var(--w) / 2));
animation-name: grow-front;
}
/* right side */
.bar i:nth-child(2) {
background: hsl(var(--hue) 70% 42%);
transform: rotateY(90deg) translateZ(calc(var(--w) / 2));
animation-name: grow-side;
}
/* lid */
.bar i:nth-child(3) {
height: var(--w);
background: hsl(var(--hue) 90% 74%);
transform-origin: center;
transform: rotateX(90deg) translateZ(calc(var(--w) / 2));
animation-name: grow-lid;
}
/* each keyframe gives only the SHORT state; the tall state is the element's own transform */
@keyframes grow-front {
from { transform: translateZ(calc(var(--w) / 2)) scaleY(var(--k)); }
}
@keyframes grow-side {
from { transform: rotateY(90deg) translateZ(calc(var(--w) / 2)) scaleY(var(--k)); }
}
@keyframes grow-lid {
from { transform: translateY(calc(var(--h) - calc(14 * var(--u)))) rotateX(90deg) translateZ(calc(var(--w) / 2)); }
}