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-overtail 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.