The perspective CSS property gives an element a 3D-space by affecting the distance between the Z plane and the user.
The strength of the effect is determined by the value. The smaller the value, the closer you get from the Z plane and the more impressive the visual effect. The greater the value, the more subtle will be the effect.
Important: Please note the perspective property doesn’t affect how the element is rendered; it simply enables a 3D-space for children elements. This is the main difference between thetransform: perspective() function and the perspective property. The first gives element depth while the later creates a 3D-space shared by all its transformed children.
/**
* Syntax
* perspective: none | <length>
*/
.parent {
perspective: 1000px;
}
.child {
transform: rotateY(50deg);
}
<div class="parent perspective"> <h1>Using perspective property on parent</h1> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> </div><!-- --><div class="parent transform"> <h1>Using transform: perspective() on children</h1> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> <div class="child"></div> </div>
* {
box-sizing: border-box;
}
body {
font-size: 20px;
}
.parent {
width: 50%;
display: inline-block;
padding: .5em;
}
.parent.perspective {
perspective: 50em;
}
.child {
margin: .5em;
width: 3em;
height: 3em;
background: tomato;
display: inline-block;
border: 1px solid rgba(0,0,0,.5);
}
.parent.perspective .child {
transform: rotateX(50deg);
background: tomato;
}
.parent.transform .child {
transform: perspective(50em) rotateX(50deg);
background: deepskyblue;
}
h1 {
font-size: 1em;
}
he above demo aims at showing the difference between the function and the property.
- On the left side, you can see the property applied to the parent (
perspective: 50em) of transformed elements (transform: rotateY(50deg)). - On the right side, the perspective is applied from the transform directly on children (
transform: perspective(50em) rotateY(50deg)).
This shows how setting perspective on the parent make all children share the same 3D-space and thus the same vanishing point.
Let’s try something even cooler: a cube with 3D transforms and perspective.
<div class="wrapper w1">
<h1><code>perspective: 1000px</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>perspective: 250px</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: 50%;
float: left;
}
.w1 {
perspective: 1000px;
}
.w2 {
perspective: 250px;
}
.wrapper h1 {
text-align: center;
}
.cube {
font-size: 4em;
width: 2em;
margin: 1.5em auto;
transform-style: preserve-3d;
transform: rotateX(-40deg) rotateY(32deg);
}
.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); }
Here is how the cube is made: it relies on two nested wrappers (one to give the cube perspective and one to wrap all the sides) and 6 elements to make the sides. Each element is given its own transform mixing translating and rotating in the 3D-space (e.g. transform: rotateX(90deg) translateZ(1em)).
Let’s finish with a demo featuring what could be the base of a real world design: a wall of photographs + captions using perspective and transform.
<div class="wrapper">
<div class="inner">
<figure>
<img src="http://lorempixel.com/200/200/nature" alt="Nature">
<figcaption>Nature picture</figcaption>
</figure>
<figure>
<img src="http://lorempixel.com/200/200/abstract" alt="Nature">
<figcaption>Abstract image </figcaption>
</figure>
<figure>
<img src="http://lorempixel.com/200/200/animals" alt="Nature">
<figcaption>Animal photo</figcaption>
</figure>
</div>
</div>
@import url(http://fonts.googleapis.com/css?family=Source Sans Pro);
* {
box-sizing: border-box;
}
body {
font-size: 16px;
}
.wrapper {
perspective: 1000px;
margin: 4em auto;
width: 37em;
}
.wrapper:hover .inner {
transform: rotate(0)
}
.inner {
transition: .3s;
transform: rotateY(40deg);
}
.inner figure {
box-shadow: -6px 6px 2px -3px rgba(100,100,100,.1);
width: 11em;
padding: 1em;
display: inline-block;
margin-right: 1em;
background: rgba(250,200,200,0.1);
border: 1px solid rgba(250,200,200,.5);
}
.inner figcaption {
text-align: center;
margin: .5em 0;
font-family: 'Source Sans Pro', sans-serif;
font-weight: bold;
color: darken(tomato, 15%);
}
.inner img {
display: block;
height: auto;
max-width: 100%;
margin: 0 auto;
-webkit-filter: sepia(75%);
}
When hovering over the wall, the children are rotated back to their normal position, cancelling the effect.
Important! Using perspective (with a value different from 0 or none) creates a new stacking context.
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-

Share
Tweet
Email
Leave a Reply