Last updated on

The perspective-origin property determines the origin for the perspective property. Think of it as the vanishing point of the current 3D-space.

Note as for the perspective property, perspective-origin has to be defined on the parent element in order to give the transformed children depth.

The perspective-origin property doesn’t do anything by itself. It has to be defined on an element along with perspective.

/**
 * Syntax 
 * perspective-origin: x-position
 * perspective-origin: x-position y-position
 * 
 * perspective-origin: <percentage> | <length> | constants | inherit
 */

.element1 { perspective-origin: 25% 75%; }

.element2 { perspective-origin: 10px 25px; }

.element3 { perspective-origin: left bottom; }

Below is a demo showing how a 3D cube behaves when altering its vanishing point by changing the perspective-origin value (constants).

<div class="wrapper w1">
  <h1><code>top left</code></h1>
  <div class="cube">
    <div class="side  front">1</div>
    <div class="side   back">6</div>
    <div class="side  right">4</div>
    <div class="side   left">3</div>
    <div class="side    top">5</div>
    <div class="side bottom">2</div>
  </div>
</div>
<div class="wrapper w2">
  <h1><code>top</code></h1>
  <div class="cube">
    <div class="side  front">1</div>
    <div class="side   back">6</div>
    <div class="side  right">4</div>
    <div class="side   left">3</div>
    <div class="side    top">5</div>
    <div class="side bottom">2</div>
  </div>
</div>
<div class="wrapper w3">
  <h1><code>top right</code></h1>
  <div class="cube">
    <div class="side  front">1</div>
    <div class="side   back">6</div>
    <div class="side  right">4</div>
    <div class="side   left">3</div>
    <div class="side    top">5</div>
    <div class="side bottom">2</div>
  </div>
</div>
<div class="wrapper w4">
  <h1><code>left</code></h1>
  <div class="cube">
    <div class="side  front">1</div>
    <div class="side   back">6</div>
    <div class="side  right">4</div>
    <div class="side   left">3</div>
    <div class="side    top">5</div>
    <div class="side bottom">2</div>
  </div>
</div>
<div class="wrapper w5">
  <h1><code>center</code></h1>
  <div class="cube">
    <div class="side  front">1</div>
    <div class="side   back">6</div>
    <div class="side  right">4</div>
    <div class="side   left">3</div>
    <div class="side    top">5</div>
    <div class="side bottom">2</div>
  </div>
</div>
<div class="wrapper w6">
  <h1><code>right</code></h1>
  <div class="cube">
    <div class="side  front">1</div>
    <div class="side   back">6</div>
    <div class="side  right">4</div>
    <div class="side   left">3</div>
    <div class="side    top">5</div>
    <div class="side bottom">2</div>
  </div>
</div>
<div class="wrapper w7">
  <h1><code>bottom left</code></h1>
  <div class="cube">
    <div class="side  front">1</div>
    <div class="side   back">6</div>
    <div class="side  right">4</div>
    <div class="side   left">3</div>
    <div class="side    top">5</div>
    <div class="side bottom">2</div>
  </div>
</div>
<div class="wrapper w8">
  <h1><code>bottom</code></h1>
  <div class="cube">
    <div class="side  front">1</div>
    <div class="side   back">6</div>
    <div class="side  right">4</div>
    <div class="side   left">3</div>
    <div class="side    top">5</div>
    <div class="side bottom">2</div>
  </div>
</div>
<div class="wrapper w9">
  <h1><code>bottom right</code></h1>
  <div class="cube">
    <div class="side  front">1</div>
    <div class="side   back">6</div>
    <div class="side  right">4</div>
    <div class="side   left">3</div>
    <div class="side    top">5</div>
    <div class="side bottom">2</div>
  </div>
</div>
.wrapper {
  width: 30%;
  display: inline-block;
  padding-bottom: 1em;
}

.wrapper h1 {
  text-align: center;
  font-size: 1.5em;
}

.cube {
  font-size: 2em;
  width: 2em;
  height: 2em;
  margin: .5em auto;
  transform-style: preserve-3d;
  perspective: 250px;
}

.w1 .cube { perspective-origin: top left; }
.w2 .cube { perspective-origin: top; }
.w3 .cube { perspective-origin: top right; }
.w4 .cube { perspective-origin: left; }
.w5 .cube { perspective-origin: center; }
.w6 .cube { perspective-origin: right; }
.w7 .cube { perspective-origin: bottom left; }
.w8 .cube { perspective-origin: bottom; }
.w9 .cube { perspective-origin: bottom right; }

.side {
  position: absolute;
  width: 2em;
  height: 2em;
  
  background: rgba(tomato, .6);
  border: 1px solid rgba(0,0,0,.5);
  
  color: white; 
  text-align: center;
  line-height: 2em;
}

.front  { transform:                  translateZ(1em); }
.top    { transform: rotateX( 90deg)  translateZ(1em); }
.right  { transform: rotateY( 90deg)  translateZ(1em); }
.left   { transform: rotateY(-90deg)  translateZ(1em); }
.bottom { transform: rotateX(-90deg)  translateZ(1em); }
.back   { transform: rotateY(-180deg) translateZ(1em); }

Hey, let’s animate the perspective-origin, just for fun!

 <div class="cube">
    <div class="side  front">1</div>
    <div class="side   back">6</div>
    <div class="side  right">4</div>
    <div class="side   left">3</div>
    <div class="side    top">5</div>
    <div class="side bottom">2</div>
  </div>
.cube {
  font-size: 5em;
  width: 2em;
  height: 2em;
  margin: 1em auto;
  transform-style: preserve-3d;
  perspective: 500px;
  animation: move-origin infinite 2s;
}

.side {
  position: absolute;
  width: 2em;
  height: 2em;
  
  background: rgba(tomato, .6);
  border: 1px solid rgba(0,0,0,.5);
  
  color: white; 
  text-align: center;
  line-height: 2em;
}

.front  { transform:                  translateZ(1em); }
.top    { transform: rotateX( 90deg)  translateZ(1em); }
.right  { transform: rotateY( 90deg)  translateZ(1em); }
.left   { transform: rotateY(-90deg)  translateZ(1em); }
.bottom { transform: rotateX(-90deg)  translateZ(1em); }
.back   { transform: rotateY(-180deg) translateZ(1em); }

@keyframes move-origin {
  0%    { perspective-origin: 0%     0%; }
  25%   { perspective-origin: 100%   0%; }
  50%   { perspective-origin: 100% 100%; }
  75%   { perspective-origin: 0%   100%; }
  100%  { perspective-origin: 0%     0%; }
}
  1. It starts at `0% 0%` (top left)
  2. Then go to `100% 0%` (top right)
  3. Then to `100% 100%` (bottom right)
  4. Then to `0% 100%` (bottom left)
  5. Then go back to 1. and restart

Related Properties

Browser Support

Chrome Safari Firefox Opera IE Android iOS
12+ Any 10+ None 10+ 3+ Any

Firefox 10-15 need -moz-, WebKit browsers may need -webkit-.