← Back to CSS Course | Chapter 8: Animations & Effects | Lesson 7 of 22

CSS 3D Transforms

A 3D transform adds real depth to the flat page — rotating an element away from the viewer, pushing it back in space, or building a scene where child elements keep their own 3D positions.

From 2D to 3D: rotateX/Y/Z

rotateX() and rotateY() tilt an element around its horizontal or vertical axis, making it appear to fold away from or toward the viewer, while rotateZ() behaves just like the familiar 2D rotate(). All three require the parent to establish a perspective for the depth effect to actually render.

Example: From 2D to 3D: rotateX/Y/Z

css
<style>
.scene {
  perspective: 400px;
  background: #eee;
  padding: 30px;
}
.box {
  transform: rotateY(45deg);
  background: steelblue;
  color: white;
  padding: 20px;
  display: inline-block;
}
</style>
<div class="scene">
  <div class="box">Tilted away from the viewer</div>
</div>

The perspective Property

perspective sets how far the viewer's eye is from the screen: a small value (like 200px) creates a dramatic, exaggerated 3D effect, while a large value (like 1500px) creates a subtle one. Without perspective set on a parent, 3D rotations render as if viewed from infinitely far away and look flat. perspective-origin shifts the vanishing point itself away from the element's center, changing which side of the 3D scene appears to recede fastest.

Example: The perspective Property

css
<style>
.dramatic {
  perspective: 200px;
  background: #eee;
  padding: 30px;
  display: inline-block;
}
.subtle {
  perspective: 1500px;
  background: #eee;
  padding: 30px;
  display: inline-block;
}
.box {
  transform: rotateY(45deg);
  background: steelblue;
  color: white;
  padding: 20px;
}
</style>
<div class="dramatic"><div class="box">Dramatic depth</div></div>
<div class="subtle"><div class="box">Subtle depth</div></div>

translate3d and translateZ

translate3d(x, y, z) moves an element in three dimensions at once, where a positive z value pushes it toward the viewer and a negative value pushes it away — combined with perspective, this changes the element's apparent size, just like real depth would.

Example: translate3d and translateZ

css
<style>
.scene {
  perspective: 500px;
}
.box {
  transform: translate3d(0, 0, 100px);
}
</style>
<div class="scene">
  <div class="box">Pushed toward the viewer, appears larger</div>
</div>

transform-style: preserve-3d

By default, a 3D-transformed element flattens its children into its own 2D plane. Setting transform-style: preserve-3d on the parent instead lets children keep their own independent 3D positions and rotations, which is essential for building layered 3D scenes like a rotating cube. backface-visibility: hidden hides an element entirely once it has rotated past 90 degrees and is facing away from the viewer, which is essential for building a convincing flip-card effect where you do not want the mirrored backside text showing through.

Example: transform-style: preserve-3d

css
<style>
.cube {
  transform-style: preserve-3d;
}
.face {
  backface-visibility: hidden;
}
</style>
<div class="cube">
  <div class="face">Front face</div>
  <div class="face">Back face, hidden once rotated away</div>
</div>

2D vs 3D Transforms

Unlike 2D transforms, which only reposition an element within the flat page plane, 3D transforms require a perspective context and the extra Z-axis functions (rotateX/Y, translateZ, matrix3d) to actually appear as depth rather than just a differently-shaped flat shadow.

Example: 2D vs 3D Transforms

css
<style>
.flat {
  transform: rotate(45deg);
}
.scene {
  perspective: 400px;
}
.depth {
  transform: rotateY(45deg);
}
</style>
<div class="flat">2D: stays flat</div>
<div class="scene"><div class="depth">3D: appears to have depth</div></div>

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.