More Animations Snippets
CSS 3D Cube — Free HTML CSS JS Snippet
CSS 3D Cube · Animations · Plain HTML, CSS & JS · Live preview
What's included
Features
About this UI Snippet
CSS 3D Cube — Six Faces via rotateY/X + translateZ, preserve-3d & Spin Animation

A CSS 3D cube renders all six faces of a cube using HTML divs and CSS 3D transforms — no WebGL, no canvas, no library. It uses the same preserve-3d technique as the 3D flip card and 3D card tilt. The cube spins continuously and can be clicked to pause and rotate manually.
The six faces
Each .face div is absolutely positioned inside the .cube container. The cube is a 140px box. Each face uses a combination of rotateY/rotateX and translateZ(70px) (half the cube size) to position it on the correct plane: .front { transform: rotateY(0deg) translateZ(70px) }, .back { transform: rotateY(180deg) translateZ(70px) }, .right { transform: rotateY(90deg) translateZ(70px) } etc.
preserve-3d
.cube { transform-style: preserve-3d } is required on the cube container. Without it, the child faces collapse to 2D and all appear stacked on the same plane.
Spin animation and click control
A @keyframes spin rotates the cube continuously. Clicking the cube toggles spinning and removes the CSS animation, allowing manual rotation via setCam(rx, ry).
Manual rotation controls
The snippet includes three view-preset buttons: Top view (rx=90, ry=0), Side view (rx=20, ry=-60), and Perspective (rx=20, ry=30). These call setCam(rx,ry) which stops the auto-spin animation and applies a specific rotateX + rotateY transform to the cube wrapper. An Auto-spin button restores the CSS keyframe animation.
The perspective container
The outer .scene div has perspective: 600px — this is the distance from the viewer to the 3D plane. A smaller value creates a more extreme fish-eye distortion; larger values produce flatter, more orthographic projections. The value 600px is close to the cube's display size (140px), giving a dramatic but not distorted 3D appearance.
Face labelling
Each face uses text labels (FRONT, BACK, LEFT, RIGHT, TOP, BOTTOM) and a distinct background colour. Replace the text and background with images using background-image: url() and background-size: cover for a textured or photographic cube.
Performance
All cube faces are hardware-accelerated via transform — no layout or paint is triggered by the rotation animation. The will-change: transform hint can be added to .cube for additional GPU compositor optimisation on animating elements.
Customising the cube appearance
Change the cube size by updating the 140px value in .cube, .scene, and translateZ(70px) — keep translateZ at exactly half the cube edge length. Each face can have a different background colour, gradient, or image. For a product showcase, place product screenshots on each face. For a game, use different textures. The cube container size and translateZ offset are the only two values you need to change to resize the cube cleanly.
Build with AI
Build, Understand, Optimize, and Extend It With AI
You don't have to work out the six-face rotation values yourself to see why each one uses exactly a 90-degree step. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly why every face needs both a rotate transform and a translateZ of half the cube's edge length, and what visually breaks if the translateZ value doesn't match half the cube size when you resize it. The same assistant can help optimize it — for instance asking whether toggling between the CSS keyframe spin and the drag-driven inline transform ever leaves the cube in an inconsistent state if a user starts dragging mid-animation. It's also useful for extending the cube: ask it to add touch drag support alongside the existing mouse drag so it works on mobile, replace the text-labeled faces with real images or product screenshots using background-image, or add momentum/inertia so releasing a drag continues spinning briefly before settling. Treat the code less like a finished artifact and more like a starting point for a conversation.
Prompt to recreate it
Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:
Build a draggable, spinning 3D cube in plain HTML, CSS, and JavaScript using only CSS 3D transforms — no WebGL, no canvas, no Three.js.
Requirements:
- Six face elements, each absolutely positioned inside a single cube container, where every face is placed onto its correct plane using a rotateX or rotateY value in exact 90-degree increments (0, 90, 180, -90) combined with a translateZ equal to exactly half the cube's edge length, so all six faces form a closed box with no gaps or overlaps.
- The cube's direct parent must set a CSS perspective value to establish the 3D viewing distance, and the cube itself must set transform-style preserve-3d so the child faces' 3D positioning isn't flattened into 2D.
- A continuous CSS keyframe animation that rotates the whole cube indefinitely, togglable on and off via a class, representing an "auto-spin" mode.
- Manual camera preset buttons that, when clicked, stop the auto-spin animation and directly set the cube's transform to a specific rotateX/rotateY combination (e.g. a reset front-facing view, an angled perspective view, and a top-down view).
- Mouse-drag rotation: pressing down on the cube stops any auto-spin, and dragging the mouse afterward continuously updates the cube's rotateX and rotateY based on the cumulative vertical and horizontal mouse movement since the last frame, releasing the mouse anywhere on the page (not just over the cube) to stop the drag.
- Ensure that switching between auto-spin, a camera preset, and manual dragging always leaves the cube's transform in a single consistent state with no leftover animation class conflicting with an inline transform.Step by step
How to Use
- 1Watch the cube spinThe cube spins continuously via CSS @keyframes. Click the cube to pause spinning and rotate manually.
- 2Move the cursor to rotate manuallyAfter clicking to pause, move the cursor over the cube to rotate it via mousemove and see all six faces.
- 3Update face contentIn the HTML panel, change the emoji, gradient background, or text inside each .face div.
- 4Change cube sizeUpdate width/height on .cube and .face (currently 140px) and translateZ to half the new size.
- 5Change spin speedUpdate the animation duration in @keyframes spin (currently 8s) in the CSS panel.
- 6Export in your formatClick "HTML" for a standalone file, "JSX" for a React component, or "Tailwind" for a React + Tailwind version.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
Each face uses a combination of rotation and translation: .front { rotateY(0deg) translateZ(70px) }, .back { rotateY(180deg) translateZ(70px) }, .right { rotateY(90deg) translateZ(70px) }, .left { rotateY(-90deg) translateZ(70px) }, .top { rotateX(90deg) translateZ(70px) }, .bottom { rotateX(-90deg) translateZ(70px) }.
Without preserve-3d on the parent .cube, all child .face elements are flattened into the 2D plane of the parent — they lose their 3D positions and all appear stacked on the same surface.
perspective: 800px sets the distance from the viewer to the z=0 plane. Lower values (400px) create more dramatic foreshortening; higher values (1200px) give subtler depth. The perspective must be on the parent of the rotating element.
Update the width/height on .cube and .face (currently 140px). Update translateZ to half the new size: a 200px cube uses translateZ(100px). Update .stage perspective proportionally.
Yes. Click "JSX" for a React component. The CSS animations and 3D transforms work identically in React. Manage the spinning state in useState and apply/remove the spinning class.
Replace the gradient background on each .face with an image background-image, or add HTML content inside each face div. The 3D positioning applies to the face div and all its contents.