Learn the basic concept of moving elements in 2d and 3d space. How to use transform functions with perspective and understand the behavior of transform-origin.
Perspective is a property that enables 3-dimensional space on an element or a parent, whose child can have various 3D transformations applied on them. Transform values like translate3D, and rotate3D have the ability to move in the third coordinate: the z-axis.
How does CSS Perspective work?
To enable 3D space, CSS property perspective needs to be defined on the parent, or if it's a child or single element child we can use function perspective(). Child elements need to have any of the 3D values in the transform property.
See what happens when we enable the CSS perspective on the below demo. You’ll see the difference between 2d and 3d space. Enable the checkbox to enable 3d space. A checkbox in the example window switches between 2d and perspective 3d space.
The perspective CSS behaves differently based on what kind of element it's applied to.
When applied on the parent it enables 3d space on the parent element only. The classic 3d cube example shown by David DeSandro gives a basic understanding of how to make a basic cube with six simple div elements or objects.
We’ll use this basic cube to understand the main properties and their behavior of the 3d space.
CSS Perspective syntax:
Using Perspective() function:
transform: perspective (<value>) <3d properties>;
value: none or any valid width value
3d properties: Accepts values with translateZ, translate3d, rotateX, rotateY, rotateZ, rotate3d, scaleZ, scale3d
document.getElelementById('#child').style.transform = 'perspective(<value>) <3d properties>';
value: none or any valid width value
document.getElelementById('#parent').style.perspective = '<value>';
What is the vanishing point?
Artists draw a horizontal line to represent eye level and select a single point on that line to draw other diagonal lines to guide the drawing. More like a railway track or road vanishing into the mountain.
Why vanishing point is important you ask?
Because it's the fundamental of 3d drawing or 3d space. We have the vanishing point in CSS called perspective-origin. By default, the perspective origin in CSS is at the center of the parent or the element using the perspective property.
In the above example, the red lines meet at one point in the distance. that point is a vanishing point. without this concept, the geometer will look isometric.
Why do we have two syntaxes for perspective?
Because they work differently and they require other properties or functions to make objects 3D.
The function perspective() is used on a single element with perspective() as a first value in transform property to create a single vanishing point perspective space. When used with transform, it creates 3d space for the element. Without perspective() function, other transform properties will still work in an orthographic direction. Since the perspective function works on individual elements, the vanishing point will always stay in the center. Move your mouse cursor to rotate the element.
As you expected. Every element can have its own 3d space when using the CSS perspective function. They rotate along their center which can de difficult to manage when creating multiple 3d elements. Because they all are independent, aligning them with a group of objects can get you unexpected results.
To solve this problem, We can rotate a group instead of rotating an individual element using the CSS perspective property on a parent.
The CSS Perspective Property:
Well, perspective is mainly used on a parent or a container element. Mainly because to keep a single vanishing point among all the children like what we see in the real world.
For example, in the below demo, we're changing the perspective-origin. You can observe how the vanishing point moves in 3d space and the cube aligns according to the reference lines coming from that single vanishing point.
When you move the mouse, we're changing transform-origin to have an understanding of moving the vanishing point across children. Rotating the parent will be just the same as rotating individual elements in 3d space.
The perspective CSS property requires another property called transform-style:perspective-3d for cross-browser compatibility. Transform-style works on parent or container elements and accepts flat or perspective-3d values.
Perspective enables 3D space when using 3D transforms. Let's see what other functions can be used to put objects in 3D space.
- translate3d(<tx>, <tx>, <tz>) : it defines a translation in x, y, and z direction. Tx is abscissa, ty represents ordinate of the translating vector and z represents z-axis. Tx, ty accepts length or percentage value. Tz can only be length.
- translateZ(<length>) : Triggers translation in Z-axis. The bigger the value it becomes bigger. When used with perspective, it looks like scaling. This is because the object is moving towards the viewer.
- scale3d(<sx>,<sy>,<sz>) : Each value defines scaling in the respective direction. Sx and Sy are scaling in x and y directions. Sz won't affect when applied on a single element because all the elements are planes and can't be scaled on the z-axis.
- scaleZ(<length>) : Just like the translate() function, Scaling in the z-axis work when applied to the parent element with some depth. Accepts valid length values.
- rotate3d(<x>, <y>, <z>, <angle>) : the function accepts x,y,z which are the direction in which the rotation should take place. Angle accepts values between 0deg to 360deg. We can specify rotation angle for single or multiple axes by using x,y, or z values which accept numeric values. rotateX(<angle>), rotateY(<angle>) and rotateZ(<angle>) take only a single angle value to rotate in the respective axis.
We have 2 sets of functions doing the exact same thing differently mainly because 3D properties like translate3d(), scale3d(), and rotate3d() enabled hardware acceleration. So selection of these functions can improve performance in some cases depending on what you want to accomplish and how many objects are there in your 3d container.
The Perspective CSS is mostly underutilized functionality mainly because there are better options available to do it right. Although CSS properties can enable 3d space in my opinion, it's not meant to be used to created complex geometry like what WebGL is able to offer. I didn't just write an article about 3d perspective to turn it down. Codepen artists came up with great ideas to create interactive and decorative elements over the past years. There are creators who get 3D CSS just right and end up creating amazing 3d UI. I have created an experiment called CSS Only Parallax Using Perspective Transforms.