How do you add 3D depth to a web page with CSS?

3D effects give flat interfaces a sense of depth by placing elements in a virtual space. In CSS this relies on the perspective property, transform-style: preserve-3d and 3D transforms such as rotateY() and translateZ(); WebGL takes over when a scene needs real lighting or hundreds of objects.

How to choose, performance and accessibility
  • Use CSS 3D for pieces people interact with: Card Flip 3D for a pricing or team card, Perspective Tilt for a product visual, 3D Carousel for a gallery; keep WebGL for immersive heroes.
  • Animate only transform and opacity so the browser can use the GPU, avoid stacking many 3D layers on mobile, and drop large rotations for prefers-reduced-motion.
  • Rotating Cube, Mouse Parallax Scene and Floating Shadows are free with their full code; the other effects on this page come with Premium.
Generator

Real 3D, not CSS perspective

The effects on this page fake depth with CSS. The SVG to 3D generator builds an actual volume: your logo is extruded, lit, it casts a shadow and you can grab it.

The preview and the image are free. The code comes with a subscription.

Open the generator
Front
Back
Right
Left
Top
Bottom

Rotating Cube

Interactive 3D cube that follows the mouse movement.

CSS 3D Interactive
View source code
HTML
<div class="demo-preview">
  <div class="demo-3d">
    <div class="cube-container">
      <div class="cube" id="cube">
        <div class="cube-face front">Front</div>
        <div class="cube-face back">Back</div>
        <div class="cube-face right">Right</div>
        <div class="cube-face left">Left</div>
        <div class="cube-face top">Top</div>
        <div class="cube-face bottom">Bottom</div>
      </div>
    </div>
  </div>
</div>
CSS
.demo-preview,
.demo-preview *,
.demo-preview *::before,
.demo-preview *::after {
  box-sizing: border-box
}

.demo-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 250px;
  overflow: hidden;
  position: relative;
  background: rgb(26, 26, 36);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
}

.demo-3d {
  width: 280px;
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.cube-container {
  width: 100px;
  height: 100px;
  perspective: 600px;
}

.cube {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
  transform: rotateX(-20deg) rotateY(-30deg);
  transition: transform 0.1s ease-out;
}

.cube-face {
  position: absolute;
  width: 100px;
  height: 100px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 14px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  backface-visibility: visible;
}

.cube-face.front {
  background: rgba(99, 102, 241, 0.8);
  transform: translateZ(50px);
}

.cube-face.back {
  background: rgba(139, 92, 246, 0.8);
  transform: rotateY(180deg) translateZ(50px);
}

.cube-face.right {
  background: rgba(217, 70, 239, 0.8);
  transform: rotateY(90deg) translateZ(50px);
}

.cube-face.left {
  background: rgba(6, 182, 212, 0.8);
  transform: rotateY(-90deg) translateZ(50px);
}

.cube-face.top {
  background: rgba(16, 185, 129, 0.8);
  transform: rotateX(90deg) translateZ(50px);
}

.cube-face.bottom {
  background: rgba(244, 63, 94, 0.8);
  transform: rotateX(-90deg) translateZ(50px);
}
JavaScript
(function() {
  // 1. Rotating Cube - Mouse interaction
  const cube = document.getElementById('cube');

  const cubeContainer = cube.parentElement;

  cubeContainer.addEventListener('mousemove', (e) => {
    const rect = cubeContainer.getBoundingClientRect();
    const x = e.clientX - rect.left - rect.width / 2;
    const y = e.clientY - rect.top - rect.height / 2;
    const rotateX = -y / 5;
    const rotateY = x / 5;
    cube.style.transform = `rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
  });

  cubeContainer.addEventListener('mouseleave', () => {
    cube.style.transform = 'rotateX(-20deg) rotateY(-30deg)';
  });
})();

Card Flip 3D

Full card flip with realistic 3D effect.

CSS 3D Hover

Perspective Tilt

Element that tilts in 3D based on cursor position.

JS 3D Mouse

Folding Panel

Panel that unfolds like paper on hover.

CSS 3D Fold

3D Button Press

Button with realistic 3D press effect.

CSS 3D Button

Layered Parallax 3D

Multiple layers with 3D depth effect.

JS 3D Parallax

Rotating Text

Text with continuous animated 3D rotation.

CSS 3D Text

3D Menu Stack

Stacked menu with depth effect on hover.

CSS 3D Menu

Isometric Grid

Isometric grid with interactive 3D cubes.

CSS 3D Isometric

Cube Auto-Rotation

3D cube with continuous automatic rotation.

CSS 3D Auto

Parallax Depth Layers

Stacked layers with 3D depth effect.

CSS 3D Depth

Fold Effect Card

Card that folds inward on hover.

CSS 3D Fold

Door Open Effect

3D door that opens to reveal the content.

CSS 3D Door

Page Turn Effect

Page turning effect on hover.

CSS 3D Book

Prism Rotation

Hexagonal prism with automatic rotation.

CSS 3D Prism

Floating Elements 3D

Floating elements with animated 3D rotation.

CSS 3D Float

3D Button Press V2

3D button with perspective press effect.

CSS 3D Button

Shadow Perspective

Card with realistic 3D shadow that reacts on hover.

CSS 3D Shadow

Mouse Parallax Scene

Multi-layered scene (stars, moon, mountains, trees) reacting to cursor at different speeds.

JS Mouse Parallax
View source code
HTML
<div class="demo-preview">
  <div class="parallax-scene" data-parallax-scene>
    <div class="parallax-layer" data-depth="0.1">
      <div class="parallax-stars">
        <span class="parallax-star" style="top:10%;left:15%"></span>
        <span class="parallax-star" style="top:20%;left:75%"></span>
        <span class="parallax-star" style="top:35%;left:45%"></span>
        <span class="parallax-star" style="top:15%;left:90%"></span>
        <span class="parallax-star" style="top:50%;left:25%"></span>
        <span class="parallax-star" style="top:8%;left:55%"></span>
        <span class="parallax-star" style="top:42%;left:80%"></span>
        <span class="parallax-star" style="top:28%;left:10%"></span>
      </div>
    </div>
    <div class="parallax-layer" data-depth="0.25" style="display:flex;align-items:flex-start;justify-content:flex-end;padding:30px 60px 0 0;">
      <div class="parallax-moon"></div>
    </div>
    <div class="parallax-layer" data-depth="0.4">
      <div class="parallax-mountains">
        <div class="parallax-mountain mountain-1"></div>
        <div class="parallax-mountain mountain-2"></div>
        <div class="parallax-mountain mountain-3"></div>
        <div class="parallax-mountain mountain-4"></div>
      </div>
    </div>
    <div class="parallax-layer" data-depth="0.6">
      <div class="parallax-trees">
        <div class="parallax-tree tree-sm"></div>
        <div class="parallax-tree tree-lg"></div>
        <div class="parallax-tree tree-md"></div>
        <div class="parallax-tree tree-sm"></div>
        <div class="parallax-tree tree-lg"></div>
        <div class="parallax-tree tree-md"></div>
        <div class="parallax-tree tree-sm"></div>
      </div>
    </div>
  </div>
</div>
CSS
.demo-preview,
.demo-preview *,
.demo-preview *::before,
.demo-preview *::after {
  box-sizing: border-box
}

.demo-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 250px;
  overflow: hidden;
  position: relative;
  background: rgb(26, 26, 36);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
}

.parallax-scene {
  width: 100%;
  height: 250px;
  position: relative;
  overflow: hidden;
  border-radius: 12px;
  background: linear-gradient(180deg, #0a0a2e 0%, #1a1a4e 50%, #2a1a3e 100%);
  cursor: crosshair;
}

.parallax-layer {
  position: absolute;
  inset: -30px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.1s ease-out;
  will-change: transform;
}

.parallax-stars {
  width: 100%;
  height: 100%;
}

.parallax-star {
  position: absolute;
  width: 3px;
  height: 3px;
  background: white;
  border-radius: 50%;
  opacity: 0.6;
}

.parallax-moon {
  width: 60px;
  height: 60px;
  background: radial-gradient(circle at 35% 35%, #fef3c7, #fbbf24);
  border-radius: 50%;
  box-shadow: 0 0 40px rgba(251, 191, 36, 0.4), 0 0 80px rgba(251, 191, 36, 0.2);
}

.parallax-mountains {
  position: absolute;
  bottom: -30px;
  width: 120%;
  left: -10%;
}

.parallax-mountain {
  position: absolute;
  bottom: 0;
  width: 0;
  height: 0;
  border-style: solid;
}

.mountain-1 {
  left: 5%;
  border-width: 0 80px 120px 80px;
  border-color: transparent transparent #1e1b4b transparent;
}

.mountain-2 {
  left: 25%;
  border-width: 0 100px 100px 100px;
  border-color: transparent transparent #2e1065 transparent;
}

.mountain-3 {
  left: 55%;
  border-width: 0 90px 130px 90px;
  border-color: transparent transparent #1e1b4b transparent;
}

.mountain-4 {
  left: 75%;
  border-width: 0 70px 90px 70px;
  border-color: transparent transparent #2e1065 transparent;
}

.parallax-trees {
  position: absolute;
  bottom: -30px;
  width: 120%;
  left: -10%;
  display: flex;
  justify-content: space-around;
  align-items: flex-end;
}

.parallax-tree {
  width: 0;
  height: 0;
  border-style: solid;
  border-color: transparent transparent #064e3b transparent;
}

.tree-sm {
  border-width: 0 12px 40px 12px;
}

.tree-md {
  border-width: 0 16px 55px 16px;
}

.tree-lg {
  border-width: 0 20px 70px 20px;
}
JavaScript
(function() {
  // ========== SPATIAL DEPTH ==========
  // ==========================================
  // 1. Mouse Parallax Scene
  // ==========================================
  document.querySelectorAll('[data-parallax-scene]').forEach(function(scene) {
    var layers = scene.querySelectorAll('.parallax-layer');
    scene.addEventListener('mousemove', function(e) {
      var rect = scene.getBoundingClientRect();
      var centerX = rect.width / 2;
      var centerY = rect.height / 2;
      var mouseX = e.clientX - rect.left - centerX;
      var mouseY = e.clientY - rect.top - centerY;
      layers.forEach(function(layer) {
        var depth = parseFloat(layer.getAttribute('data-depth')) || 0.1;
        var moveX = mouseX * depth * 0.5;
        var moveY = mouseY * depth * 0.5;
        layer.style.transform = 'translate(' + moveX + 'px, ' + moveY + 'px)';
      });
    });
    scene.addEventListener('mouseleave', function() {
      layers.forEach(function(layer) {
        layer.style.transform = 'translate(0, 0)';
      });
    });
  });
})();

Depth Card

Card with layered elements (background, text, icon) separating in 3D on hover with translate3d.

CSS 3D Hover

Floating Elements

UI elements floating and oscillating as if weightless with different animation durations.

CSS Animation Float

Perspective Scroll

Content at different Z depths creating a space flight effect with CSS perspective and translateZ.

CSS Perspective 3D

Layered Paper

Stack of paper sheets with realistic shadows and slight rotation, spreading out on hover.

CSS Hover Shadow

Isometric Grid

Interactive isometric grid where blocks rise and fall based on cursor proximity.

JS Mouse Isometric

Depth of Field

Foreground/background with blur that changes focus on hover, simulating depth of field.

CSS Blur Hover

3D Room

Content placed on the floor and walls of a CSS perspective room that rotates on drag.

JS 3D Drag
♦
★
♥

Floating Shadows

Elements with shadows moving independently as if a dynamic light source is moving.

JS Mouse Shadow
View source code
HTML
<div class="demo-preview">
  <div class="float-shadow-container" data-float-shadow>
    <div class="float-shadow-el">
      <div class="float-shadow-shape fs-shape-1">&#9830;</div>
      <div class="float-shadow-shadow"></div>
    </div>
    <div class="float-shadow-el">
      <div class="float-shadow-shape fs-shape-2">&#9733;</div>
      <div class="float-shadow-shadow"></div>
    </div>
    <div class="float-shadow-el">
      <div class="float-shadow-shape fs-shape-3">&#9829;</div>
      <div class="float-shadow-shadow"></div>
    </div>
  </div>
</div>
CSS
.demo-preview,
.demo-preview *,
.demo-preview *::before,
.demo-preview *::after {
  box-sizing: border-box
}

.demo-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 250px;
  overflow: hidden;
  position: relative;
  background: rgb(26, 26, 36);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
}

.float-shadow-container {
  width: 100%;
  height: 250px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 30px;
  cursor: crosshair;
}

.float-shadow-el {
  position: relative;
  transition: transform 0.3s ease;
}

.float-shadow-shape {
  width: 60px;
  height: 60px;
  border-radius: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  position: relative;
  z-index: 2;
}

.fs-shape-1 {
  background: linear-gradient(135deg, #6366f1, #818cf8);
}

.fs-shape-2 {
  background: linear-gradient(135deg, #ec4899, #f472b6);
  border-radius: 50%;
}

.fs-shape-3 {
  background: linear-gradient(135deg, #10b981, #34d399);
}

.float-shadow-shadow {
  position: absolute;
  bottom: -15px;
  left: 50%;
  transform: translateX(-50%);
  width: 50px;
  height: 10px;
  background: radial-gradient(ellipse, rgba(0, 0, 0, 0.35) 0%, transparent 70%);
  border-radius: 50%;
  transition: all 0.3s ease;
  z-index: 1;
}
JavaScript
(function() {
  // ==========================================
  // 9. Floating Shadows - Dynamic light source
  // ==========================================
  document.querySelectorAll('[data-float-shadow]').forEach(function(container) {
    var elements = container.querySelectorAll('.float-shadow-el');
    container.addEventListener('mousemove', function(e) {
      var rect = container.getBoundingClientRect();
      var mx = e.clientX - rect.left;
      var my = e.clientY - rect.top;
      var centerX = rect.width / 2;
      var centerY = rect.height / 2;
      var lightX = (mx - centerX) / centerX;
      var lightY = (my - centerY) / centerY;

      elements.forEach(function(el) {
        var shape = el.querySelector('.float-shadow-shape');
        var shadow = el.querySelector('.float-shadow-shadow');
        // Move shadow opposite to light direction
        var shadowX = -lightX * 15;
        var shadowY = lightY * 5 + 5;
        var shadowScale = 1 + Math.abs(lightY) * 0.3;
        shadow.style.transform = 'translateX(calc(-50% + ' + shadowX + 'px)) scaleX(' + shadowScale + ')';
        shadow.style.opacity = 0.6 - Math.abs(lightY) * 0.2;
        // Lift shape slightly toward light
        shape.style.transform = 'translate(' + (lightX * 3) + 'px, ' + (-Math.abs(lightY) * 5) + 'px)';
        // Dynamic box shadow on shape
        shape.style.boxShadow = ((-lightX * 8)) + 'px ' + ((-lightY * 8 + 4)) + 'px 20px rgba(0,0,0,0.3)';
      });
    });
    container.addEventListener('mouseleave', function() {
      elements.forEach(function(el) {
        var shape = el.querySelector('.float-shadow-shape');
        var shadow = el.querySelector('.float-shadow-shadow');
        shadow.style.transform = 'translateX(-50%)';
        shadow.style.opacity = '0.35';
        shape.style.transform = 'translate(0, 0)';
        shape.style.boxShadow = '';
      });
    });
  });
})();

Orbit Circle

Elements orbiting around a central point with offset-path: circle(). Varied speeds and directions.

CSS offset-path Orbit
View source code
HTML
<div class="demo-preview">
  <div class="mp-orbit-scene">
    <div class="mp-orbit-ring mp-orbit-ring--1"></div>
    <div class="mp-orbit-ring mp-orbit-ring--2"></div>
    <div class="mp-orbit-center"></div>
    <div class="mp-orbit-dot mp-orbit-dot--1"></div>
    <div class="mp-orbit-dot mp-orbit-dot--2"></div>
    <div class="mp-orbit-dot mp-orbit-dot--3"></div>
  </div>
</div>
CSS
.demo-preview,
.demo-preview *,
.demo-preview *::before,
.demo-preview *::after {
  box-sizing: border-box
}

.demo-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 250px;
  overflow: hidden;
  position: relative;
  background: rgb(26, 26, 36);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
}

.mp-orbit-scene {
  width: 260px;
  height: 260px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mp-orbit-center {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: linear-gradient(135deg, #8b5cf6, #7c3aed);
  box-shadow: 0 0 20px rgba(139, 92, 246, 0.4);
  z-index: 2;
}

.mp-orbit-ring {
  position: absolute;
  border-radius: 50%;
  border: 1px dashed rgba(255, 255, 255, 0.1);
}

.mp-orbit-ring--1 {
  width: 140px;
  height: 140px;
}

.mp-orbit-ring--2 {
  width: 210px;
  height: 210px;
}

.mp-orbit-dot {
  position: absolute;
  border-radius: 50%;
  top: 50%;
  left: 50%;
}

.mp-orbit-dot--1 {
  width: 16px;
  height: 16px;
  background: #ec4899;
  box-shadow: 0 0 10px rgba(236, 72, 153, 0.5);
  offset-path: circle(70px);
  animation: mpOrbit 4s linear infinite;
  margin: -8px 0 0 -8px;
}

.mp-orbit-dot--2 {
  width: 12px;
  height: 12px;
  background: #06b6d4;
  box-shadow: 0 0 10px rgba(6, 182, 212, 0.5);
  offset-path: circle(105px);
  animation: mpOrbit 7s linear infinite reverse;
  margin: -6px 0 0 -6px;
}

.mp-orbit-dot--3 {
  width: 8px;
  height: 8px;
  background: #f59e0b;
  box-shadow: 0 0 8px rgba(245, 158, 11, 0.5);
  offset-path: circle(105px);
  animation: mpOrbit 5s linear infinite;
  margin: -4px 0 0 -4px;
}

@keyframes mpOrbit {
  to {
    offset-distance: 100%;
  }
}
JavaScript
/* Pure CSS — no JavaScript required */

SVG Path Follow

Glowing dot following an SVG curve with a ghost trail echoed with a time offset.

CSS SVG Trail

Bezier Curve

Ball following a cubic Bezier curve with visible control points and ground shadow.

CSS Bezier Animation

Infinity Loop

Dot following a lemniscate-shaped (∞) path with a glowing trail halo.

CSS Path Infinity

Spiral Path

Dot traveling along an outward-expanding spiral via a complex SVG path.

CSS Spiral SVG

Bounce Path

Ball following a bounce trajectory with progressively decreasing arcs.

CSS Bounce Physics

Wave Path

Three dots of different sizes and colors following a sine wave with time offsets.

CSS Wave Stagger

Multi Orbit

Miniature solar system with 5 planets on 3 orbits at varied speeds and distances.

CSS Orbit System

Path Drawing

SVG path that draws itself with stroke-dashoffset while a dot follows the same trajectory.

CSS SVG Draw

Rollercoaster

Cart following a rollercoaster track with offset-rotate: auto for natural orientation.

CSS offset-rotate Path

AR/VR & WebXR

📊Stats
⚙Settings
👤Profile

Spatial UI Panels

Floating UI panels arranged in an arc in 3D space with parallax effect.

CSS 3D Perspective UI
View source code
HTML
<div class="demo-preview">
  <div class="xr-spatial-panels">
    <div class="xr-panel"><span class="xr-panel-icon">&#128202;</span>Stats</div>
    <div class="xr-panel"><span class="xr-panel-icon">&#9881;</span>Settings</div>
    <div class="xr-panel"><span class="xr-panel-icon">&#128100;</span>Profile</div>
  </div>
</div>
CSS
.demo-preview,
.demo-preview *,
.demo-preview *::before,
.demo-preview *::after {
  box-sizing: border-box
}

.demo-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 250px;
  overflow: hidden;
  position: relative;
  background: rgb(26, 26, 36);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
}

/* Variables du design system du site, dont ce code dépend (valeurs de css/style.css — à adapter librement). */
.demo-preview {
  --text-secondary: #a1a1aa;
}

.xr-spatial-panels {
  width: 100%;
  height: 100%;
  perspective: 800px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
}

.xr-panel {
  width: 80px;
  height: 100px;
  background: rgba(99, 102, 241, 0.15);
  border: 1px solid rgba(99, 102, 241, 0.3);
  border-radius: 12px;
  backdrop-filter: blur(10px);
  padding: 10px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 0.65rem;
  color: var(--text-secondary);
  text-align: center;
  transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1);
}

.xr-panel:nth-child(1) {
  transform: rotateY(-25deg) translateZ(30px);
}

.xr-panel:nth-child(2) {
  transform: rotateY(0deg) translateZ(50px);
}

.xr-panel:nth-child(3) {
  transform: rotateY(25deg) translateZ(30px);
}

.xr-panel:hover {
  transform: rotateY(0deg) translateZ(70px) scale(1.1);
}

.xr-panel-icon {
  font-size: 1.5rem;
  margin-bottom: 6px;
}
JavaScript
/* Pure CSS — no JavaScript required */

360 Viewer

Interactive panorama with drag-to-rotate for an immersive 360-degree view.

JS Drag Panorama

AR Object Placer

3D object placement simulation on a surface with detection grid.

CSS AR Placement

Holographic Display

Holographic display with scanline, prismatic reflections and light pulsation.

CSS Hologram Animation
View source code
HTML
<div class="demo-preview">
  <div class="xr-holo-display">
    <div class="xr-holo-box">
      <div class="xr-holo-scanline"></div>
      <div class="xr-holo-prism"></div>
    </div>
  </div>
</div>
CSS
.demo-preview,
.demo-preview *,
.demo-preview *::before,
.demo-preview *::after {
  box-sizing: border-box
}

.demo-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 250px;
  overflow: hidden;
  position: relative;
  background: rgb(26, 26, 36);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
}

.xr-holo-display {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}

.xr-holo-box {
  width: 120px;
  height: 120px;
  position: relative;
  border: 1px solid rgba(99, 102, 241, 0.3);
  border-radius: 8px;
  background: rgba(99, 102, 241, 0.05);
  animation: xrHoloPulse 3s ease-in-out infinite;
}

.xr-holo-scanline {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  background: linear-gradient(90deg, transparent, rgba(99, 102, 241, 0.6), transparent);
  animation: xrScanline 2s linear infinite;
}

.xr-holo-prism {
  position: absolute;
  inset: 0;
  background: linear-gradient(135deg, transparent 30%, rgba(99, 102, 241, 0.1) 45%, rgba(168, 85, 247, 0.1) 55%, transparent 70%);
  animation: xrPrism 4s linear infinite;
}

@keyframes xrScanline {
  from {
    top: 0;
  }

  to {
    top: 100%;
  }
}

@keyframes xrHoloPulse {

  0%,
  100% {
    box-shadow: 0 0 20px rgba(99, 102, 241, 0.2);
  }

  50% {
    box-shadow: 0 0 40px rgba(99, 102, 241, 0.4), inset 0 0 20px rgba(99, 102, 241, 0.1);
  }
}

@keyframes xrPrism {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}
JavaScript
/* Pure CSS — no JavaScript required */

Spatial Audio Dir

3D audio directional indicator with concentric waves and moving sound source.

CSS Audio Spatial

Portal Effect

Portal to another dimension: rotating ring and pulsing light core, scattered with particles.

CSS JS Portal
Select
Grab
Point

Hand Tracking UI

Gesture-reactive interface simulated with a custom cursor following the mouse.

JS Gestures UI
View source code
HTML
<div class="demo-preview">
  <div class="xr-hand-tracking" id="xrHandTracking">
    <div class="xr-hand-btn">Select</div>
    <div class="xr-hand-btn">Grab</div>
    <div class="xr-hand-btn">Point</div>
    <div class="xr-hand-cursor" id="xrHandCursor"></div>
  </div>
</div>
CSS
.demo-preview,
.demo-preview *,
.demo-preview *::before,
.demo-preview *::after {
  box-sizing: border-box
}

.demo-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 250px;
  overflow: hidden;
  position: relative;
  background: rgb(26, 26, 36);
  color: rgb(255, 255, 255);
  font-family: sans-serif;
}

/* Variables du design system du site, dont ce code dépend (valeurs de css/style.css — à adapter librement). */
.demo-preview {
  --text-secondary: #a1a1aa;
}

.xr-hand-tracking {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.xr-hand-cursor {
  width: 24px;
  height: 24px;
  border: 2px solid #6366f1;
  border-radius: 50%;
  position: absolute;
  pointer-events: none;
  transition: transform 0.1s ease;
}

.xr-hand-cursor::after {
  content: '';
  position: absolute;
  inset: 4px;
  border-radius: 50%;
  background: rgba(99, 102, 241, 0.3);
}

.xr-hand-btn {
  padding: 10px 20px;
  background: rgba(99, 102, 241, 0.15);
  border: 1px solid rgba(99, 102, 241, 0.3);
  border-radius: 8px;
  color: var(--text-secondary);
  font-size: 0.8rem;
  cursor: pointer;
  transition: all 0.3s ease;
  margin: 0 8px;
}

.xr-hand-btn:hover {
  background: rgba(99, 102, 241, 0.3);
  transform: scale(1.05);
}

.xr-hand-btn.active {
  background: rgba(99, 102, 241, 0.4);
  border-color: #6366f1;
}
JavaScript
(function() {
  /* Suivi main XR (fx-0048) restauré depuis .bak-strip — 12/08/2026 */
  // Hand Tracking UI — le curseur suit la souris (fx-0048)
  (function() {
    var container = document.getElementById('xrHandTracking');
    var cursor = document.getElementById('xrHandCursor');
    if (!container || !cursor) return;

    container.addEventListener('mousemove', function(e) {
      var rect = container.getBoundingClientRect();
      cursor.style.left = (e.clientX - rect.left - 12) + 'px';
      cursor.style.top = (e.clientY - rect.top - 12) + 'px';
    });

    container.querySelectorAll('.xr-hand-btn').forEach(function(btn) {
      btn.addEventListener('click', function() {
        container.querySelectorAll('.xr-hand-btn').forEach(function(b) {
          b.classList.remove('active');
        });
        btn.classList.add('active');
        cursor.style.transform = 'scale(0.8)';
        setTimeout(function() {
          cursor.style.transform = 'scale(1)';
        }, 200);
      });
    });
  })();
})();

Immersive Depth Scroll

Z-depth layers that react to mouse movement for an immersive parallax effect.

CSS 3D Parallax Depth

XR Environment

Complete immersive scene with starry skybox, floating 3D objects and perspective grid floor.

CSS JS Environment

3D Product Showcase

Real interactive 3D model (.glb): 360° drag rotation, auto-rotate, realistic shadows and augmented reality view on mobile. The premium packshot that sells.

💡 Ideal for: product page, limited edition, configurator, e-commerce hero, premium listing, Black Friday.

model-viewer .glb / AR Product Premium

Frequently Asked Questions

How to create a flip card in CSS? +

Use a container with perspective:1000px, an inner card with transform-style:preserve-3d and transition. The back face has backface-visibility:hidden and rotateY(180deg). On hover, the card rotates 180deg.

What is the difference between perspective and 3D transform? +

perspective defines the distance between the viewer and the element -- it goes on the PARENT. 3D transforms (rotateX, rotateY, translateZ) deform the element itself. The smaller the perspective, the more pronounced the effect.

How to create a 3D carousel in CSS? +

Place items in a circle with rotateY and translateZ in a container with transform-style:preserve-3d. Each item has rotateY(i * 360/n deg) translateZ(radius). Animate the container rotation to scroll through.

Is WebGL necessary for web 3D effects? +

Not for most effects: CSS perspective + transforms are sufficient for cards, carousels and parallax. WebGL (via Three.js) is only necessary for complex 3D scenes: models, textures, lights, physics.

Are CSS 3D effects performant? +

Yes. 3D transforms are processed by the GPU. Avoid combining transform with filter on the same element. Limit the number of elements with preserve-3d as each 3D layer consumes GPU memory.

Similar Categories