Overview
CSS 3D cubes are the canonical teaching example for the difference between scene perspective and element transforms. The scene owns perspective (the camera distance); the cube owns transform-style: preserve-3d (so children render in shared 3D space); each face owns its own transform: rotateX/Y + translateZ(half-side) composition. Get one of those three responsibilities wrong and the cube collapses to a flat square.
When to use it
Reach for a 3D cube as a teaching demo, a navigation primitive (carousel of six panels), or a logo treatment for a product that wants depth without modeling tools. Skip it for production content where each face would carry meaningful text — backface-visible faces are hard to keep accessible, and the rotation makes reading content nearly impossible mid-spin.
How it works
Set perspective: 720px on the scene wrapper; smaller values exaggerate the perspective (fisheye-ish), larger values flatten it (telephoto-ish). Set transform-style: preserve-3d on the cube itself so the six face elements render in shared 3D space rather than each being flattened. Each face: first rotate to its target axis (e.g. rotateY(90deg) for the right face), then translateZ(half the cube side) to push the face out from the center. Transform order matters — rotate first, then translateZ, never the reverse.
Production gotchas
perspective-origin defaults to 50% 50%— the camera sits at the cube’s center. Move the origin (e.g. perspective-origin: 50% 30%) to bias the camera up, which is what makes a cube look like you are looking slightly down on it instead of dead-on. Without backface-visibility hidden, the back faces show through translucent fronts and the cube looks broken; set backface-visibility: hidden on every face. If your cube is rotating and one face flickers in/out of view, you have a z-fighting issue — add translateZ(0.01px) to the back face so it never sits at exactly the same depth as the front.
Accessibility
A spinning cube under prefers-reduced-motion: reduce should freeze at a readable angle — not the default rest position (which is usually a face-on flat view), but a slight rotation that still shows the cube IS a cube. Face content should be real DOM text, not images, so that backface-hidden faces are still indexed and screen-reader-accessible during pauses.
References
Implementation depth
A CSS cube only works when scene and faces have separate responsibilities. The scene owns perspective, the cube owns transform-style: preserve-3d, and each face owns rotate plus translateZ in the correct order.
Use it for teaching or decorative navigation, not for dense reading content. Backface visibility, z-fighting, and perspective-origin changes can all affect legibility, so reduced motion should freeze at an angle that still communicates depth.