Blog / CSS

CSS 3D: Perspective, Rotations and Depth Effects

Master CSS 3D transforms to create immersive interfaces. Rotating cube, carousel, card flip and depth effects with interactive demos.

Introduction to 3D transformations

CSS 3D transformations allow creating impressive visual effects without JavaScript. Thanks to the perspective, transform-style properties and 3D rotation functions, you can build immersive interfaces.

In this guide, we will explore 5 essential 3D effects: the rotating cube, the carousel, the card flip, depth effects and extruded 3D text. Each demo is interactive and the code is ready to copy.

🛠
Key properties

perspective defines the observer's distance. transform-style: preserve-3d allows children to live in 3D space. backface-visibility hides the back face of elements.

1. Rotating 3D cube

The 3D cube is a classic for understanding CSS transformations. Each face is positioned in space using rotateY() and translateZ().

Front
Back
Right
Left
Top
Bottom
cube-3d.css
.cube-scene {
  width: 150px;
  height: 150px;
  perspective: 600px;
}

.cube {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
  animation: cubeRotate 8s infinite linear;
}

.cube-face {
  position: absolute;
  width: 150px;
  height: 150px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 2px solid rgba(99, 102, 241, 0.5);
  background: rgba(99, 102, 241, 0.2);
}

/* Positioning the 6 faces */
.front  { transform: rotateY(0deg) translateZ(75px); }
.back   { transform: rotateY(180deg) translateZ(75px); }
.right  { transform: rotateY(90deg) translateZ(75px); }
.left   { transform: rotateY(-90deg) translateZ(75px); }
.top    { transform: rotateX(90deg) translateZ(75px); }
.bottom { transform: rotateX(-90deg) translateZ(75px); }

@keyframes cubeRotate {
  0% { transform: rotateX(0deg) rotateY(0deg); }
  100% { transform: rotateX(360deg) rotateY(360deg); }
}

Key points

  • translateZ(75px): Half the cube size (150px/2) to center each face
  • transform-style: preserve-3d: Essential on the container for children to be in 3D
  • perspective on the parent: Creates the depth of field

The 3D carousel arranges elements in a circle around a central axis. Each element is positioned at a different angle (360deg / number of elements).

carousel-3d.css
.carousel-scene {
  width: 100%;
  height: 280px;
  position: relative;
  perspective: 1000px;
}

.carousel {
  width: 200px;
  height: 250px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform-style: preserve-3d;
  animation: carouselRotate 20s infinite linear;
}

.carousel-item {
  position: absolute;
  width: 200px;
  height: 250px;
  border-radius: 12px;
  box-shadow: 0 25px 50px rgba(0,0,0,0.3);
}

/* 6 items = 360/6 = 60deg between each */
.carousel-item:nth-child(1) { transform: rotateY(0deg) translateZ(300px); }
.carousel-item:nth-child(2) { transform: rotateY(60deg) translateZ(300px); }
.carousel-item:nth-child(3) { transform: rotateY(120deg) translateZ(300px); }
.carousel-item:nth-child(4) { transform: rotateY(180deg) translateZ(300px); }
.carousel-item:nth-child(5) { transform: rotateY(240deg) translateZ(300px); }
.carousel-item:nth-child(6) { transform: rotateY(300deg) translateZ(300px); }

@keyframes carouselRotate {
  from { transform: translate(-50%, -50%) rotateY(0deg); }
  to { transform: translate(-50%, -50%) rotateY(-360deg); }
}
💡
Calculating translateZ

For N elements, the ideal translateZ distance is approximately: width / (2 * tan(180/N)). For 6 elements of 200px: 200 / (2 * tan(30)) = ~173px minimum.

3. 3D Card Flip

The card flip effect reveals a hidden face on hover or click. The backface-visibility: hidden property is essential to hide the back face of each side.

Front Face

Hover or click

Hidden content revealed! Perfect for info cards, products or memory games.

Click to flip
card-flip.css
.flip-card {
  width: 280px;
  height: 180px;
  perspective: 1000px;
  cursor: pointer;
}

.flip-card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  transition: transform 0.8s cubic-bezier(0.4, 0, 0.2, 1);
  transform-style: preserve-3d;
}

.flip-card:hover .flip-card-inner {
  transform: rotateY(180deg);
}

.flip-card-front,
.flip-card-back {
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.flip-card-front {
  background: linear-gradient(135deg, #6366f1, #8b5cf6);
}

.flip-card-back {
  background: linear-gradient(135deg, #8b5cf6, #d946ef);
  transform: rotateY(180deg);
}

4. Depth effect (Layers)

By stacking layers with different translateZ values, we create a striking depth effect. On hover, the layers spread apart to reveal the structure.

Layer 1 - Base
Layer 2
Layer 3
Layer 4 - Top
depth-layers.css
.depth-scene {
  width: 350px;
  height: 250px;
  position: relative;
  transform-style: preserve-3d;
  transform: rotateX(10deg) rotateY(-10deg);
  transition: transform 0.3s ease;
}

.depth-layer {
  position: absolute;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.3s ease;
}

.layer-1 {
  width: 100%; height: 100%;
  background: rgba(99, 102, 241, 0.9);
  transform: translateZ(0px);
}

.layer-2 {
  width: 90%; height: 85%;
  left: 5%; top: 7.5%;
  background: rgba(139, 92, 246, 0.85);
  transform: translateZ(40px);
}

.layer-3 {
  width: 80%; height: 70%;
  left: 10%; top: 15%;
  background: rgba(217, 70, 239, 0.8);
  transform: translateZ(80px);
}

.layer-4 {
  width: 70%; height: 55%;
  left: 15%; top: 22.5%;
  background: linear-gradient(135deg, #f43f5e, #f59e0b);
  transform: translateZ(120px);
}

/* Expansion on hover */
.depth-scene:hover {
  transform: rotateX(0deg) rotateY(0deg);
}

.depth-scene:hover .layer-2 { transform: translateZ(60px); }
.depth-scene:hover .layer-3 { transform: translateZ(120px); }
.depth-scene:hover .layer-4 { transform: translateZ(180px); }

5. Extruded 3D text

3D text uses multiple stacked text-shadow to simulate extrusion. Combined with rotation, the effect is spectacular.

CSS 3D
text-3d.css
.text-3d-scene {
  perspective: 500px;
}

.text-3d {
  font-size: 4rem;
  font-weight: 900;
  color: #6366f1;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  transform: rotateX(15deg) rotateY(-15deg);
  transform-style: preserve-3d;
  animation: text3dFloat 4s ease-in-out infinite;

  /* Extrusion via text-shadow empiles */
  text-shadow:
    1px 1px 0 #5558e3,
    2px 2px 0 #4a4dd5,
    3px 3px 0 #3f42c7,
    4px 4px 0 #3437b9,
    5px 5px 0 #292cab,
    6px 6px 0 #1e219d,
    7px 7px 0 #13168f,
    8px 8px 0 #080b81,
    9px 9px 15px rgba(0,0,0,0.4);
}

@keyframes text3dFloat {
  0%, 100% {
    transform: rotateX(15deg) rotateY(-15deg) translateY(0);
  }
  50% {
    transform: rotateX(10deg) rotateY(-10deg) translateY(-10px);
  }
}
⚠️
Performance

Multiple text-shadows can impact performance on low-powered devices. Limit the number of layers and test on mobile.

Best practices

Here are the essential recommendations for performant and accessible 3D effects.

Performance

  • Use will-change: transform on animated elements to optimize GPU rendering
  • Limit the 3D elements simultaneously visible on the page
  • Avoid complex shadows on continuously rotating elements
  • Test on mobile: mobile GPUs are less powerful

Accessibility

accessibility.css
/* Respect user preferences */
@media (prefers-reduced-motion: reduce) {
  .cube,
  .carousel,
  .text-3d {
    animation: none;
  }

  .flip-card-inner,
  .depth-layer {
    transition: none;
  }
}

/* Alternative for touch interactions */
@media (hover: none) {
  .flip-card:hover .flip-card-inner {
    transform: none;
  }
}

Browser compatibility

  • Chrome, Edge, Firefox, Safari: Full support for several years
  • iOS Safari: Watch out for bugs with transform-style in certain contexts
  • Prefixes: No longer necessary for modern 3D properties

Conclusion

CSS 3D transformations open a world of creative possibilities. By mastering perspective, transform-style and rotation functions, you can create memorable interfaces without JavaScript.

Experiment with values, combine techniques and don't forget: subtlety is often more effective than excess. A well-placed 3D effect draws attention; too many effects tire the user.

🎨
Go further

Find dozens of ready-to-use 3D effects in our effects library, with one-click copyable code.