There are four primary two-dimensional transform functions: *rotate() , scaLe() , skew()* , and *transLate()* . Six other functions let us transform an element in a single dimension: *scaLeX() and scaLeY() ; skewX() and skewY()* ; and *transLateX()* and *transLateY()* .

rotate()

A rotation transform spins an element around its origin by the angle specified around the *transform-origin* point. Using* rotate()* tilts an element clockwise (positive angle values) or counterclockwise (negative angle values). Its effect is much like a windmill or pinwheel, as pictured below, where the purple box has been rotated 55 degrees from its start position, shown by the dotted line.

The *rotate()* function accepts values in angle units. Angle units are defined by the CSS Values and Units Module Level 3^{4} specification. These may be* deg* (degrees), *rad* (radians), *grad* (gradians), or *turn* ( turn ) units. One complete rotation is equal to *360deg , 6.28rad , 400grad* , or *1turn* .

Rotation values that exceed one rotation (say,* 540deg* or *1.5sturn* ) are rendered according to their remaindered value, unless animated or transitioned. In other words, *540deg* is rendered the same as* 180deg* (540 degrees minus 360 degrees) and *1.5sturn* is rendered the same as *1.5sturn* (1.5 minus 1). But a transition or animation from *0deg* to *540deg* or *1turn* to *1.5sturn* rotates the element one-and-a-half times.

**2D Scaling Functions: scale(), scaleX(), and scaleY()**

With scaling functions, we can increase or decrease the rendered size of an element in the X- dimension ( scaLex() ), Y-dimension (* scaLeY()* ), or both ( *scaLe()* ). Scaling is illustrated below, where the border illustrates the original boundaries of the box, and the + marks its center point. The red box (left) is scaled by a factor or two (right).

Each scale function accepts a multiplier or factor as its argument. This multiplier can be just about any positive or negative number. Percentage values aren’t supported. Positive multipliers greater than *1* increase the size of an element. For example, *scaLe(1.5)* increases the size of the element in the X and Y directions 1.5 times, as illustrated below. The northern cardinal drawing on the left is not transformed. The cardinal drawing on the right has been scaled to 1.5 times the size of the original illustration.

*Cardinal drawing by kattekrab from Openclipart.*

Positive multipliers between *0* and *1* reduce the size of an element. Negative multipliers scale the element, but they also flip or reflect it along one or both axes. In the image below, the northern cardinal drawing on the left is not transformed, while the one on the right has a negative scaling transformation ( *transform: scaLe(-i.5)* ) applied.

Using *scaLe(1)* creates an **identity transformation**, which means it’s drawn to the screen as if no scaling transformation was applied. Using *scaLe(1)* won’t change the drawn size of an element, but the negative value causes the element to be reflected. Even though the element doesn’t appear transformed, it still triggers a new stacking context and containing block.

You can also scale the X- and Y-dimensions separately by passing two arguments to the *scaLe()* function, such as* scaLe(1.5, 2)* . The first argument scales the X-dimension; the second scales the Y-dimension. We could, for example, reflect an object along the X-axis alone using *scaLe(-1, 1)* . Passing a single argument scales both dimensions by the same factor.

**2D Translation Functions: translatexQ, translateYQ, and translate()**

Translating an element offsets its painted position from its layout position by the specified distance. As with other transforms, translating an element doesn’t change its *offsetLeft* or *offsetTop* positions. It does, however, affect where it’s visually positioned on screen.

The 2D translation functions—* transLateX() , transLateY()* , and *transLate()* —accept lengths or percentages for arguments. Length units include pixels *( px ), em , rem ,* and viewport units ( *vw* and *vh* ).

The *translateX()* function changes the horizontal rendering position of an element. If an element is positioned zero pixels from the left, *transform: transitionX(50px)* shifts its rendered position 50 pixels to the right of its start position. Similarly, *translateY* changes the vertical rendering position of an element. A transform of *transform: transitionY(50px)* offsets the element vertically by 50 pixels.

With *translate()* , we can shift an element vertically and horizontally using a single function. It accepts up to two arguments: the X translation value, and the Y translation value. The image below shows the effect of an element with a *transform* value of *translate(120%, -50px)* , where the left green square is in the original position, and the right green square is translated 120% horizontally and -50 pixels vertically from its containing element (the dashed border).

Passing a single argument to *translate* is the equivalent of using *translateX* ; the Y translation value will be set to zero. Using *translate()* is the more concise option. Applying *transLate(100px, 200px)* is the equivalent of *transLateX(100px) transLateY(200px)* .

Positive translation values move an element to the right (for *transLateX* ) or downward (for *transLateY*). Negative values move an element to the left ( *transLateX* ) or upward ( *transLateY* ).

Translations are particularly great for moving items left, right, up, or down. Updating the value of the *Left, right , top* , and *bottom* properties forces the browser to recalculate layout information for the entire document. But transforms are calculated *after* the layout has been calculated. They affect where the elements appear on screen, but not their actual dimensions. Yes, it’s weird to think about document layout and rendering as separate concepts, but in terms of browsers, they are.

skew, skewX, **and** skewY

**Skew transformations** shift the angles and distances between points while keeping them in the same plane. Skew transformations are also known as *shear transformations*, and they distort the shapes of elements, as seen below, where a rectangle is skewed 45 degrees along its X-dimension—the dashed line representing the original bounding box of the element.

The skew functions*— skew() , skewX()* , and *skewY()* —accept most angle units as arguments. Degrees, gradians, and radians are valid angle units for the skew functions, while turn units, perhaps obviously, are not.

The *skewx()* function shears an element in the X direction (or horizontally). In the image below, the left object isn’t transformed, while the right object reveals the effect of *transform: skewX(30deg)* .

*skewx* accepts a single parameter, which again must be an angle unit. Positive values shift the element to the left, and negative values shift it towards the right.

Similarly, *skewY* shears an element in the Y direction (vertically). The image below shows the effect of* transform: skewY(30deg)* .

With *skewY* , points to the right of the origin are shifted downward with positive values. Negative values shift these points upward.

This brings us to the *skew()* function. The *skew()* function requires one argument, but accepts up to two. The first argument skews an element in the X direction, and the second skews it in the Y direction. If only one argument is provided, the second value is assumed to be zero, making it the equivalent of skewing in the X direction alone. In other words, *skew(45deg)* renders the same as *skewx(45deg)* .

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