CSS Advanced
CSS 3D Transforms
3D transforms extend 2D ones into depth. By adding a perspective and rotating around the X, Y, or Z axis, flat elements appear to tilt and turn in space. With transform-style: preserve-3d you can build flip cards and even cubes.
Adding perspective
Perspective creates the illusion of depth by defining how far the viewer is from the z=0 plane. A smaller value makes the 3D effect more dramatic. Set it on the parent with the perspective property, or per element inside transform.
.scene { perspective: 600px; } /* on the parent */
.card { transform: perspective(600px) rotateY(30deg); }| Function | Rotates around | Looks like |
|---|---|---|
| rotateX(deg) | Horizontal axis | Tilting forward/back |
| rotateY(deg) | Vertical axis | Turning like a door |
| rotateZ(deg) | Depth axis | Spinning flat (same as 2D rotate) |
| translateZ(len) | Moving toward/away from viewer | Closer or farther |
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: sans-serif; display:flex; gap:40px; padding:50px; background:#0b1020;
perspective: 700px; }
.panel { width:110px; height:130px; border-radius:12px; color:#fff;
display:flex; align-items:center; justify-content:center; font-weight:bold;
transition: transform .5s ease; }
.x { background:#6366f1; } .x:hover { transform: rotateX(45deg); }
.y { background:#ec4899; } .y:hover { transform: rotateY(45deg); }
.z { background:#10b981; } .z:hover { transform: rotateZ(30deg); }
</style>
</head>
<body>
<div class="panel x">rotateX</div>
<div class="panel y">rotateY</div>
<div class="panel z">rotateZ</div>
</body>
</html>Flip cards with preserve-3d
To flip a card, stack a front and back face, rotate the back 180 degrees, and rotate the whole inner container on hover. transform-style: preserve-3d keeps the faces in 3D space, and backface-visibility: hidden hides whichever face points away.
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: sans-serif; display:grid; place-items:center; height:260px; background:#111827; }
.scene { perspective: 900px; }
.card { width:170px; height:200px; position:relative;
transform-style: preserve-3d; transition: transform .6s; }
.scene:hover .card { transform: rotateY(180deg); }
.face { position:absolute; inset:0; border-radius:14px;
display:flex; align-items:center; justify-content:center;
font-size:22px; font-weight:bold; color:#fff;
backface-visibility: hidden; }
.front { background:linear-gradient(135deg,#22d3ee,#3b82f6); }
.back { background:linear-gradient(135deg,#f472b6,#a855f7);
transform: rotateY(180deg); }
</style>
</head>
<body>
<div class="scene">
<div class="card">
<div class="face front">FRONT</div>
<div class="face back">BACK</div>
</div>
</div>
</body>
</html>backface-visibility
When an element rotates past 90 degrees you normally see a mirror image of its back. backface-visibility: hidden makes that hidden face disappear, which is essential for clean flip effects.
<!DOCTYPE html>
<html>
<head>
<style>
body { display:grid; place-items:center; height:240px; background:#020617; perspective:800px; }
.coin { width:120px; height:120px; border-radius:50%;
background:radial-gradient(circle at 35% 30%,#fde68a,#f59e0b);
animation: spin 3s linear infinite; }
@keyframes spin { to { transform: rotateY(360deg); } }
</style>
</head>
<body>
<div class="coin"></div>
</body>
</html>Set perspective on the parent scene (not each card) so multiple 3D children share a consistent vanishing point.
3D transforms only look three-dimensional when a perspective is applied. Without it, rotateY just squashes the element horizontally.
Key points
- perspective gives the scene depth; smaller values look more dramatic.
- rotateX, rotateY, and rotateZ turn elements around each axis.
- transform-style: preserve-3d keeps child faces in 3D space.
- backface-visibility: hidden hides the reverse of a rotated face.
- Flip cards combine two absolutely positioned faces and a hover rotate.
