CSSperspective & perspective-origin

perspective & perspective-origin for 3D

perspective creates a 3D viewing space for child elements, making 3D transforms visible. It's essential for 3D effects like card flips, rotations, and depth effects. perspective-origin controls the vanishing point where parallel lines appear to meet.

Understanding perspective

CSS
<!-- perspective: creates 3D viewing space -->
.container {
  perspective: 1000px;
  /* Creates 3D space for children -->
}

.child {
  transform: rotateY(45deg);
  /* 3D rotation now visible -->
}

<!-- Without perspective: no 3D effect -->
<!-- With perspective: child appears in 3D space -->

/* perspective value: distance to viewer -->
.close-perspective {
  perspective: 500px;
  /* Closer to viewer: more extreme 3D effect -->
}

.far-perspective {
  perspective: 2000px;
  /* Far from viewer: subtle 3D effect -->
}

/* Practical values -->
.default {
  perspective: 1000px;  /* balanced -->
}

.dramatic {
  perspective: 600px;   /* exaggerated 3D -->
}

.subtle {
  perspective: 1500px;  /* mild 3D -->
}
Common perspective values

Value

Effect

Use Case

500px

Extreme 3D distortion

Dramatic effects

800px

Strong 3D effect

Noticeable depth

1000px

Balanced 3D

Default, well-balanced

1500px

Subtle 3D

Gentle depth

2000px+

Very subtle

Minimal 3D

CSS
<!-- 3D card flip with perspective -->
<div class="scene">
  <div class="card">
    <div class="card-face front">Front</div>
    <div class="card-face back">Back</div>
  </div>
</div>

.scene {
  perspective: 1000px;
  width: 200px;
  height: 200px;
}

.card {
  position: relative;
  width: 100%;
  height: 100%;
  transition: transform 0.6s;
  transform-style: preserve-3d;
}

.card-face {
  position: absolute;
  width: 100%;
  height: 100%;
  backface-visibility: hidden;
}

.back {
  transform: rotateY(180deg);
}

.scene:hover .card {
  transform: rotateY(180deg);
}

<!-- Card flips in 3D space -->

/* 3D box effect -->
.scene {
  perspective: 1000px;
}

.box {
  width: 100px;
  height: 100px;
  position: relative;
  transform-style: preserve-3d;
  animation: rotate-box 4s infinite linear;
}

@keyframes rotate-box {
  from { transform: rotateX(0) rotateY(0); }
  to { transform: rotateX(360deg) rotateY(360deg); }
}

<!-- Box rotates in 3D -->

/* Tilting effect with perspective -->
.scene {
  perspective: 800px;
}

.element {
  transition: transform 0.3s;
}

.element:hover {
  transform: rotateX(10deg) rotateY(10deg);
  /* Tilts in 3D based on hover -->
}
perspective-origin: viewing angle

CSS
<!-- perspective-origin: where you view from -->
.container {
  perspective: 1000px;
  perspective-origin: center;
  /* Default: view from center -->
}

.element {
  transform: rotateY(45deg);
}

<!-- View from center point -->

/* Different viewing angles -->
.from-top {
  perspective: 1000px;
  perspective-origin: center top;
  /* View from above -->
}

.from-left {
  perspective: 1000px;
  perspective-origin: left center;
  /* View from left side -->
}

.from-corner {
  perspective: 1000px;
  perspective-origin: top left;
  /* View from top-left corner -->
}

/* Percentage values -->
.custom {
  perspective: 1000px;
  perspective-origin: 25% 75%;
  /* View from custom point -->
}

<!-- Affects how 3D transforms appear -->

/* Practical: card flip from different angles -->
.card-container {
  perspective: 1000px;
  perspective-origin: right center;
  /* View from right side -->
}

.card {
  transition: transform 0.6s;
}

.card:hover {
  transform: rotateY(180deg);
  /* Flip appears from right perspective -->
}
Advanced 3D with perspective

CSS
<!-- Multiple 3D transformations -->
.scene {
  perspective: 1200px;
}

.element {
  transition: transform 0.4s;
}

.element:hover {
  transform: rotateX(20deg) rotateY(20deg) translateZ(50px);
  /* Tilt and move toward viewer -->
}

<!-- Complex 3D motion -->

/* 3D gallery with perspective -->
.gallery {
  perspective: 1000px;
  display: flex;
  gap: 20px;
}

.item {
  width: 150px;
  height: 150px;
  transform-style: preserve-3d;
  transition: transform 0.3s;
}

.item:hover {
  transform: rotateY(15deg) rotateZ(-5deg);
  /* Items tilt in 3D -->
}

<!-- Gallery items appear in 3D space -->

/* Depth layering -->
.scene {
  perspective: 1000px;
}

.layer-1 { transform: translateZ(0px); }
.layer-2 { transform: translateZ(50px); }
.layer-3 { transform: translateZ(100px); }

<!-- Layers appear at different depths -->

/* transform-style: preserve-3d for nested 3D -->
.scene {
  perspective: 1000px;
}

.container {
  transform-style: preserve-3d;
  transform: rotateX(10deg);
}

.child {
  transform: translateZ(50px);
  /* Child's translateZ is in parent's 3D space -->
}

<!-- Nested 3D transformations work correctly -->

/* Practical: dropdown menu with 3D perspective -->
.menu-trigger {
  perspective: 1000px;
}

.menu {
  transform-origin: top center;
  transform-style: preserve-3d;
  transition: transform 0.3s;
  opacity: 0;
  transform: rotateX(-90deg) translateZ(-10px);
}

.menu.open {
  opacity: 1;
  transform: rotateX(0deg) translateZ(0px);
}

<!-- Menu rotates down in 3D space -->
Performance and best practices

CSS
<!-- Perspective on container, not individual elements -->
.good {
  perspective: 1000px;
  /* Apply once to container -->
}

.good > * {
  transform: rotateY(45deg);
  /* All children use same perspective -->
}

.bad {
  perspective: 1000px;
}

.bad > * {
  perspective: 1000px;
  /* Don't repeat: inefficient -->
}

<!-- Apply perspective once to parent -->

/* Use backface-visibility for efficiency -->
.element {
  backface-visibility: hidden;
  /* Hide element when facing away from viewer -->
  /* Improves performance for complex 3D -->
}

/* GPU-accelerated 3D rendering -->
.element {
  perspective: 1000px;
  /* Creates GPU layer for 3D -->
}

.child {
  transform: translateZ(0);
  /* Forces GPU acceleration -->
}

<!-- Modern browsers handle 3D well -->

/* Respect prefers-reduced-motion -->
@media (prefers-reduced-motion: reduce) {
  * {
    perspective: none;
    transform: none;
  }
}

<!-- Accessibility: disable 3D for motion-sensitive users -->

/* Testing perspective in DevTools -->
/* Open 3D view in DevTools (Chrome) -->
/* See perspective layers and depths -->
/* Helps debug 3D transforms -->
Note
`perspective` creates a 3D viewing space; common values 800px-1500px. Lower values = more extreme 3D effect. Always apply perspective to parent, not individual elements. Use `transform-style: preserve-3d` for nested 3D, and `backface-visibility: hidden` to hide elements facing away. Modern browsers render 3D efficiently with GPU acceleration.
Next
3D transforms: [3D Transforms](/css/transforms-3d).