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-
Leave a Reply