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.
Hover to blow the faces apart. One custom property moves all six.
Your edited version
translateZ(var(--d)) instead of a fixed half-side distance.--d — one declaration moves all six faces.transition on transform, the change animates even though only a custom property was touched.translateZ(var(--d))transition on a var()-driven transformspin continues underneath<div class="scene" tabindex="0">
<div class="cube">
<div></div><div></div><div></div>
<div></div><div></div><div></div>
</div>
</div>
.scene {
--s: 110px;
--d: calc(var(--s) / 2); /* distance of each face from the centre */
display: grid;
place-items: center;
width: 300px;
height: 300px;
perspective: 800px;
cursor: pointer;
}
.scene:hover,
.scene:focus {
--d: 115px;
}
.cube {
position: relative;
width: var(--s);
height: var(--s);
transform-style: preserve-3d;
animation: spin 10s linear infinite;
}
.cube > * {
position: absolute;
inset: 0;
border-radius: 6px;
background: rgb(255 77 157 / 0.35);
border: 1px solid rgb(255 77 157 / 0.85);
transition: transform 0.6s cubic-bezier(0.3, 1.5, 0.5, 1);
}
.cube > :nth-child(1) { transform: rotateY(0deg) translateZ(var(--d)); }
.cube > :nth-child(2) { transform: rotateY(90deg) translateZ(var(--d)); }
.cube > :nth-child(3) { transform: rotateY(180deg) translateZ(var(--d)); }
.cube > :nth-child(4) { transform: rotateY(-90deg) translateZ(var(--d)); }
.cube > :nth-child(5) { transform: rotateX(90deg) translateZ(var(--d)); }
.cube > :nth-child(6) { transform: rotateX(-90deg) translateZ(var(--d)); }
@keyframes spin {
from { transform: rotateX(-24deg) rotateY(0deg); }
to { transform: rotateX(-24deg) rotateY(360deg); }
}
@use 'sass:list';
@use '../mixins' as *;
$turns: (rotateY(0deg), rotateY(90deg), rotateY(180deg), rotateY(-90deg), rotateX(90deg), rotateX(-90deg));
.d-explode {
--s: 84px;
--d: calc(var(--s) / 2); // how far each face sits from the centre
display: grid;
place-items: center;
width: 210px;
height: 210px;
transform-style: preserve-3d;
cursor: pointer;
&:hover,
&:focus {
--d: 86px;
}
&__cube {
position: relative;
width: var(--s);
height: var(--s);
transform-style: preserve-3d;
animation: d-explode-spin 10s linear infinite;
}
i {
position: absolute;
inset: 0;
border-radius: 6px;
@include face(var(--hot), 35%);
// The transform depends on --d, so changing --d transitions every face at once.
transition: transform 0.6s cubic-bezier(0.3, 1.5, 0.5, 1);
@for $n from 1 through 6 {
&:nth-child(#{$n}) {
transform: #{list.nth($turns, $n)} translateZ(var(--d));
}
}
}
}
@keyframes d-explode-spin {
from {
transform: rotateX(-24deg) rotateY(0deg);
}
to {
transform: rotateX(-24deg) rotateY(360deg);
}
}