# 3D Transform Functions in CSS

There are nine functions for creating 3D transforms. Each of these functions modifies the Z- coordinates of an element and/or its children, in addition to the X- and Y-coordinates. Remember, Z-coordinates are points along the plane that sit perpendicular to the viewer. With the exception of rotatez() , these functions create and change the illusion of depth on screen.

rotateX() and rotateY()

The rotatex() and rotateY() functions rotate an element around the X- and Y-axes respectively. Using rotatex() creates a somersault effect, causing an object to flip top-over­tail around a horizontal axis. With rotateY() , the effect is more like that of a spinning top, rotating around a vertical axis.

Like rotate() , both rotatex() and rotateY() accept an angle measurement as an argument. This angle can be expressed in degrees ( deg ), radians ( rad ), gradians ( grad ), or turn (turn ) units. As mentioned earlier in the chapter, rotatez() works the same way as rotate() . It’s a relic from when 2D and 3D transforms were defined by separate specifications.

Positive angle values for rotatex() cause an element to tilt backwards, as shown in the image below, where transform: rotate(45deg) is applied.

Negative angle values for rotatex() do the opposite, causing the element to tilt forward, as shown below, where transform: rotate(-45deg) is applied.

Negative angles for rotateY() cause the element to tilt counterclockwise. In the image below, the element is rotated -55 degrees around the Y-axis (transform: rotateY(-55deg) ).

Positive values tilt it clockwise, as shown below ( transform: rotateY(55deg) ).

As an aside, the three images above have a perspective value of 200px . We’ll discuss the perspective property later in this chapter. For now, it’s enough to know that this property adds a sense of depth and exaggerates the effect of the three-dimensional rotation. Compare the image above to the image below. Both have been rotated along the Y-axis by 55 degrees ( transform: rotateY(55deg) ), but in the image below, the parent container has a perspective value of none . Our object looks more squished than rotated. Use perspective on a container element when creating a 3D transform.

Rotating around Multiple Axes with rotate3d()

Sometimes we want to rotate an object around more than one axis. Perhaps you want to rotate an element counterclockwise and tilt it by 45 degrees, as in the image below, where our object is rotated around both the X- and Y-axes by 45 degrees.

This is what rotate3d() does. It’s a function that accepts four arguments. The first three make up an X, Y and Z direction vector, and each of these should be a number. The fourth argument for rotate3d() should be an angle. The transformed object will be rotated by the angle around the direction vector defined by the first three arguments.

What those first three numbers are matters less than the ratio between them. For example, transform: rotate3d(100,5,0,15deg); and transform: rotate3d(20,1,0,15deg); have equivalent 3D matrices and produce the same effect.

That said, due to way the rotate3d matrix gets calculated, a declaration such as transform: rotate3d(1, 500, 0, 15deg); won’t produce an effect significantly different from transform: rotate3d(1, 1, 0, 15deg); .

Just about any non-zero value for any of the first three parameters creates a tilt along that axis. Zero values prevent a tilt. As you may have guessed, rotatex(45deg) is the equivalent of rotate3d(1, 0, 0, 45deg) , and rotateY(25deg) could also be written as rotate3d(0, 1, 0, 25deg) .

If the first three arguments are 0 (such as transform: rotate3d(0, 0, 0, 45deg) ), the element won’t be transformed. Using negative numbers for the X, Y, or Z vector arguments is valid; it will just negate the value of the angle. In other words, rotate3d(-1, 0, 0, 45deg) is equivalent to rotate3d(1, 0, 0, -45deg) .

Using rotate3d() rotates an element by the given angle along multiple axes at once. If you want to rotate an element by different angles around multiple axes, you should use rotateX() , rotateY() , and rotate() or rotateZ() separately.

The perspective() Function

The perspective() function controls the foreshortening of an object when one end is tilted towards the viewer. Foreshortening is a specific way of drawing perspective—that is, simulating three dimensions when you only have two dimensions. With foreshortening, the ends of objects that are tilted towards the viewer appear larger, and the ends furthest from the viewer appear smaller. Foreshortening mimics the distortion that occurs when you view an object up close versus viewing it at a distance.

The more technical definition, pulled from the CSS Transforms Module Level 2 specification, says that perspective() “specifies a perspective projection matrix.” The definition continues:

This matrix scales points in X and Y based on their Z value, scaling points with positive Z values away from the origin, and those with negative Z values towards the origin. Points on the Z=0 plane are unchanged.

In practice, this means that perspective() will have a visible effect only when some of an object’s points have a non-zero Z-coordinate. Use it with another 3D function in a transform list (for example, transform: perspective(400px) rotateX(45deg) ), or apply it to the child of a transformed parent.

The perspective() function accepts a single argument. This argument must be a length greater than zero. Negative values are invalid, and the transform won’t be applied. Lower values create a more exaggerated foreshortening effect, as you can see below. In this image, the value of our transform is perspective(10px) rotate3d(1,1,1,-45deg) .

Higher values create a moderate amount of foreshortening. The next image illustrates the impact of a higher perspective value. Its transform property value is perspective(500px) rotate3d(1,1,1,-45deg) .

Order really matters when working with the perspective() function. A good rule of thumb is to list it first, as we’ve done in the examples here. You can list it elsewhere in the transform list (for example, rotate3d(1,0,1,-45deg) perspective(100px) ), but the resulting current transform matrix doesn’t create much of an effect.

There’s also a point of diminishing returns with the perspective() function (and with the perspective property, as well). Increasing the argument’s value beyond a certain threshold will create little difference in how the element and its children are painted to the screen.

Translating Depth with translateZ() and translate3d()

Earlier in this chapter, we discussed how to translate an element horizontally or vertically using transLatex() and transLateY() . However, we can also translate along the Z-axis. There are two functions that allow us to do this: transLatez() and transLate3d() . We can combine them with transitions to create zoom effects, or mimic the feeling of moving through a chute.

The transLatez() function accepts a single length parameter as its argument. Length units are the only valid units for this function. Remember that we’re projecting three-dimensional coordinates into a two-dimensional space, so percentages don’t make much sense. The transLatez() function shifts the object towards or away from the user by the specified length. Negative values shift the element or group away from the user—in effect shrinking it—as can be seen below with transform: transLateZ(-150px) .

Positive values shift the element towards the viewer, making it appear larger. Sometimes the effect is to fill the entire viewport, thereby engulfing the viewer, as seen below with transform: transLateZ(150px) .

If the value of transLatez() is large enough, the element disappears from view. That’s because it’s moved behind the viewer in this imagined 3D space. Similarly, if the value of transLatez() is small enough-say transLatez(-40000px) —the element will disappear from view because it’s now “too far” from the viewer and too small to draw on screen.

transLate3d() is a more concise way of translating in two or three directions at once. It accepts three arguments: one each for the X, Y, and Z directions. Translation values for the X and Y direction arguments may be lengths or percentages, but the Z direction argument (the third argument) must be a length value. Keep in mind that transLateX(50%) transLateY(10%) transLateZ(100px) is the equivalent of transLate3d(50%, 10%, 100px) . Use transLate3d() when you want to translate more than one dimension and you also want more concise code.

Scaling the Z-dimension: scaleZ() and scale3d()

We can also scale an object’s Z-dimension using the scaLeZ() and scaLe3d() functions. The scaLeZ() function transforms points along the Z-axis alone, while scaLe3d() lets us scale all three dimensions at once. Scaling the Z-dimension changes the depth of an object, and in some combinations can be used to create zoom effects. Experiment with them and see.

The scaLeZ() function accepts a number as its argument. As with scaLeX() and scaLeY() , positive values greater than 1 increase the size of the element’s Z-dimension. Values between 0 and 1 decrease its size. Negative values between 0 and -1 decrease the element’s size along the Z-dimension, while values less than -1 increase it. Since these values are negative, however, the element and its children are inverted. In the image below, the left die shows an element group with transform: scaLez(0.5) applied. The box on the right has a transformation of scaLez(-0.5) applied. Notice that the positions of the six face and one face have been swapped in the example with a negative scale.

The scaLe3d() function accepts three arguments—all of which are required in order for this function to work. The first argument scales the X-dimension. The second argument scales its Y-dimension, and the third argument scales the Z-dimension. As with translate3d() , the scale3d() function is just a more concise way to write transforms that scale in multiple dimensions. Rather than using scaleX(1.2) scaleY(5) scaleZ(2) , for example, you could use scale3d(1.2, 5, 2) .

Transform functions are only part of what you need to create 3D transforms. You’ll also need CSS properties that manage how objects are drawn in a simulated three-dimensional space. These properties affect the perception of depth and distance.

Source: Brown Tiffany B (2021), CSS , SitePoint; 3rd edition.