The HTML
The structure is simple: a container for the 3D scene, an element for the cube, and six divs for the faces.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Cube in CSS</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="scene">
<div class="cube">
<div class="face front"></div>
<div class="face back"></div>
<div class="face right"></div>
<div class="face left"></div>
<div class="face top"></div>
<div class="face bottom"></div>
</div>
</div>
</body>
</html>
The CSS
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
}
.scene {
width: 200px;
height: 200px;
perspective: 800px;
}
.cube {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
animation: rotate-cube 6s infinite linear;
}
.face {
width: 100%;
height: 100%;
position: absolute;
background-color: rgba(0, 0, 255, 0.3);
border: 2px solid rgba(0, 0, 0, 0.5);
}
.front {
transform: translateZ(100px);
}
.back {
transform: translateZ(-100px) rotateY(180deg);
}
.right {
transform: rotateY(90deg) translateZ(100px);
}
.left {
transform: rotateY(-90deg) translateZ(100px);
}
.top {
transform: rotateX(90deg) translateZ(100px);
}
.bottom {
transform: rotateX(-90deg) translateZ(100px);
}
@keyframes rotate-cube {
0% {
transform: rotate3d(0, 1, 0, 0deg);
}
100% {
transform: rotate3d(0, 1, 0, 360deg);
}
}
What’s happening
perspective: 800px on .scene creates the depth effect. The lower the value, the stronger (and more distorted) the effect.
transform-style: preserve-3d on .cube tells the browser to keep the children in 3D space. Without it, the faces flatten out.
Each face is positioned with translateZ (to move it away from the center) and rotateX or rotateY (to orient it). The cube is 200px wide, so we translate by 100px (half) to put the faces in the right place.
The rotate-cube animation rotates the cube on the Y axis over 6 seconds.
Taking it further
- Change
rotate3d(0, 1, 0, 360deg)torotate3d(1, 1, 0, 360deg)for rotation on two axes - Put content (text, images) inside the faces
- Play with colors and opacity
- Add
:hoverto control the rotation when hovered
The code is intentionally minimal. It’s up to you to adapt it. If you code this kind of experiment by hand, take a look at useful Vim commands - it’s an editor built for this kind of quick iteration.
