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 the transform: perspective()
function and the perspective
property. The first gives element depth while the later creates a 3D-space shared by all its transformed children.
.parent {
perspective: 1000px;
}
.child {
transform: rotateY(50deg);
}
The 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.
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.
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.
Syntax
perspective: none | <length>;
- Initial value:
none
- Applies to: transformable elements
- Inherited: no
- Percentages: n/a
- Computed value: the keyword
none
or an absolute length - Animation type: by computed value
Values
/* Keyword value */
perspective: none;
/* Length values */
perspective: 10px;
perspective: 2rem;
/* Global values */
perspective: inherit;
perspective: initial;
perspecive: revert;
perspective: unset;
Browser support
IE | Edge | Firefox | Chrome | Safari | Opera |
---|---|---|---|---|---|
10 | All | 10 1 | 12 2 | 4 2 | 15 2 |
Android Chrome | Android Firefox | Android Browser | iOS Safari | Opera Mobile |
---|---|---|---|---|
All | All | 3 2 | 3.2 2 | 62 |
1 Firefox 10-15 supported with prefix
-moz-
2 Chrome 12-35, Safari 4-8, Safari iOS 3.2-8.4, Opera 3.2, and Android Browser 3-4.4.4 supported with prefix
-webkit-
Simple yet very effective!
This will be there in the future 3D design world I think. :)
I know I’m late to the party, but I just want to add something else:
If you’re using Compass with Sass and want to use the perspective mixin, they tell you to do this:
@include perspective( perspective );
.Now, according to Compass’ documentation: “…’perspective’ is a unitless number…”.
So you would do something like this:
@include perspective( 1000 );
The problem is that this is wrong.In order for the perspective to work you DO have specify a unit (px, %, em or rem).
Like so:
@include perspective( 1000px );
And the output would be:
—
I decided to look around to see what other reputable sites say about the
perspective
property, and found out several things:This article in 24Ways.org has it wrong. Note: That article is from December 2010, so I’m not sure if the spec changed since then and now a unit is required.
W3Schools.com has it wrong, of course!. Not only has it wrong because its examples don’t use units, but even more so, because in the list of supported browsers they have Firefox crossed out and we know this works just fine in Firefox (even without vendor prefixes). Note: The term “reputable” obviously does not apply to W3Schools.com, we all know this now :).
As I said above, Compass’ documentation has it wrong too.
MDM (Mozilla Developer Network) has it right.
Safari Developer Library has it right.
Gonna post this same information on Twitter in less than 140 characters :) – lol
There, Tiwtted.
Used ALL 140 characters, lol.
I’ve always used this site as a reference for all my CSS3 developments.
Just wanted to share my work, though it’s basic, I’ve tried to be creative with it.
http://cybernext.in/Services
Here, I’ve used Perspective twice, one inside the other, to get a better 3D effect for the signboard. I had to use double backgrounds:
.signboard //background
{
transform: perspective(1000px);
transform-style: preserve-3d;
}
Then I used Transform and Transition to move the board when hovered
Cool work man!
I’m sorry, I can’t continue with the article until I know what you actually meant by this line:
Did you mean “the closer you get to the Z plane” or “the farther you get from the Z plane”? What you’ve written is just wrong.
The meaning implied here is “the closer you get TO the Z plane”. Must have been a typo.
If you put a smaller value, say 200, the element/3D object appears up close and the effect appears more ‘prominent’.
Whereas if you put a greater value, say 1000, our view appears to be shifted farther away from the object and we see the ‘wider picture’. And as a result the effect doesn’t seem so prominent.
Imagine holding a cube 2 cm from your face as compared to keeping it at a distance of 50 cm. This distance is exactly what is represented by the value of perspective.
@Vin Thanks for the clear explanation!
Actually the perspective affects the rendering in webkit engines, it’s usually not seen on desktop environments, but on iPhone or other smartphones having retina display, you’ll often find the rendering of your child elements blurry, a small example..
The image below shows a table where one of the parent elements (.row in this case), has a perspective of ‘none’, as you can see the picture is sharp and nice.
The next image, shows exact same table, but where the parent element (.row), is having a perspective of 4000, and the result rendered on retina displays is really different:
So the perspective surely affects the rendering!
Seems like images is stripped out :)
Good graphic: http://snaps.lucasrolff.com/znk8ypb3hfgdwcs.png
Bad graphic: http://snaps.lucasrolff.com/oocvxlvk2eooar2.png
Easy to understand!
Any ideas for IE9 fallback?
IE9 is obsolete. Stop wasting your time on IE9. Tell your client to upgrade their browsers.
Very helpful Paul, thank you.
give a perspective about html?
Very nice explanation on ‘perspective’ that it doesn’t affect how the element is rendered; it simply enables a 3D-space for children elements.
Thank you!
What about the
perspective()
function. Does anyone know what which browsers support this function? I’ve looked around a little but couldn’t find anything.A quick test suggest that perspective() works in Safari 11, Firefox 58, Chrome 65 and IE11. Although IE11 doesn’t support multiple transformations as used in the MDN demo.
It’s 2020 and this breaks my head. Thanks for the explanation!