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.
Every tread is the same flat slab pivoting on the pole. One index turns it 30° further and lifts it one step higher: that is the whole spiral.
Your edited version
rotateX(90deg).--u, so the staircase is the same share of a gallery card, the editor and a recording canvas. The numbers below are those units — the strips even carry theirs as plain numbers in --x, --y and --l, and the CSS multiplies each by --u.transform-origin: calc(-5 * var(--u)) 50%, a point five units to the left of the slab, which is where the pole's axis is. Every rotation now pivots around the pole.rotateY(i × 30deg) turns the tread around the pole, translateY(calc(i × -8 × var(--u))) lifts it one step. Turn + lift = spiral.transform-origin on the pole axistranslateY + rotateY from one --isides as strips round the edge, corners as facetscrossed planes as a round pole<div class="scene">
<div class="stairs">
<b></b>
<b></b>
<i style="--i:0"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:1"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:2"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:3"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:4"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:5"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:6"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:7"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:8"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:9"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:10"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:11"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:12"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
<i style="--i:13"><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s><s></s></i>
</div>
</div>
.scene {
/* one base unit: every length below is a multiple of it, so the staircase is the same share of
a card, the editor, a full screen and a recording canvas */
--u: 0.41vmin;
perspective: calc(800 * var(--u));
}
.stairs {
position: relative;
width: calc(130 * var(--u));
height: calc(136 * var(--u));
transform-style: preserve-3d;
animation: spin 16s linear infinite;
}
.stairs i {
--hue: calc(253 - var(--i) * 6); /* violet at the bottom, teal at the top */
position: absolute;
left: calc(50% + 5 * var(--u)); /* start just outside the pole */
top: calc(98 * var(--u));
width: calc(58 * var(--u));
height: calc(28 * var(--u));
/* an inner line plus a soft shade instead of a hard border: treads near eye level are seen
almost edge-on, where a hairline breaks up; the shade survives. The glow is here, on the 14
treads, not on the 140 side strips: a blur on every strip cost four screen refreshes a frame */
box-shadow:
inset 0 0 0 calc(1 * var(--u)) hsl(var(--hue) 90% 82%),
inset 0 0 calc(8 * var(--u)) hsl(var(--hue) 90% 82% / 0.25),
0 0 calc(10 * var(--u)) hsl(var(--hue) 85% 64% / 0.6);
border-radius: 0 calc(6 * var(--u)) calc(6 * var(--u)) 0;
background: hsl(var(--hue) 85% 64% / 0.62);
transform-origin: calc(-5 * var(--u)) 50%; /* on the pole's axis */
transform-style: preserve-3d;
transform:
translateY(calc(var(--i) * -8 * var(--u))) /* one step up ... */
rotateY(calc(var(--i) * 30deg)) /* ... and 30deg further round */
rotateX(90deg); /* lie flat */
}
/* The sides go all the way round the tread: both long edges, the outer end and the two rounded
corners (three short facets each), so the side follows the rounding. Each strip starts at a
point on the edge (--x, --y), turns to run along it (--a), then folds straight down one step. */
.stairs s {
position: absolute;
left: calc(var(--x) * var(--u));
top: calc(var(--y) * var(--u));
width: calc((var(--l) + 0.5) * var(--u)); /* a hair longer, so neighbours overlap: no seams */
height: calc(8 * var(--u));
background: hsl(var(--hue) 45% 30% / 0.82); /* less see-through than the top */
transform-origin: 0 0;
transform: rotate(calc(var(--a) * 1deg)) rotateX(-90deg);
}
.stairs s:nth-child(1) { --x: 0; --y: 0; --l: 52; --a: 0; }
.stairs s:nth-child(2) { --x: 0; --y: 28; --l: 52; --a: 0; }
.stairs s:nth-child(3) { --x: 58; --y: 6; --l: 16; --a: 90; }
.stairs s:nth-child(4) { --x: 52; --y: 0; --l: 3.11; --a: 15; }
.stairs s:nth-child(5) { --x: 55; --y: 0.8; --l: 3.11; --a: 45; }
.stairs s:nth-child(6) { --x: 57.2; --y: 3; --l: 3.11; --a: 75; }
.stairs s:nth-child(7) { --x: 58; --y: 22; --l: 3.11; --a: 105; }
.stairs s:nth-child(8) { --x: 57.2; --y: 25; --l: 3.11; --a: 135; }
.stairs s:nth-child(9) { --x: 55; --y: 27.2; --l: 3.11; --a: 165; }
.stairs s:nth-child(10) { --x: 0; --y: 0; --l: 28; --a: 90; } /* the inner end, at the pole */
/* pole: two crossed planes */
.stairs b {
position: absolute;
left: calc(50% - 4 * var(--u));
top: 0;
width: calc(8 * var(--u));
height: 100%;
border-radius: calc(4 * var(--u));
background: linear-gradient(90deg, #3a3f63, #eceefb, #3a3f63);
opacity: 0.85;
}
.stairs b + b {
transform: rotateY(90deg);
}
@keyframes spin {
from { transform: rotateX(-20deg) rotateY(0deg); }
to { transform: rotateX(-20deg) rotateY(360deg); }
}