With the CSS transform property, you can apply a 2D or 3D transformation to an HTML element. You can visually control an element by moving, rotating, scaling, or tilting it, and even adjusting the perspective for a 3D transformed element. This article will take you through the CSS transform property – you will learn everything you need to know about 2D and 3D transformations through a few examples. Let’s start.
1. The basic syntax of the CSS transform property
transform: none|transform-functions|initial|inherit;
The syntax says the transform property should:
- not use any transformation (value <none>),
- use one of the transform-functions (we will take a look at the values and their meanings in the following paragraph),
- use value <initial>, which means we will set the property to its default value,
- use value <inherit>, which means the property will be inherited from its parent element.
2. CSS transform property functions: translating, rotating, scaling, moving, or skewing elements
Let’s go through the basic functions of CSS transform property and take a look at each function and its meaning in general:
- translate() function moves an element horizontally and/or vertically – a two-dimensional vector defines how much the element should be moved in each direction. If you want to translate the movement in 3D, you should use translate3d() instead.
- scale() function controls the size of the element, therefore it also affects the size of a font, and even the padding, height, and width of an element. scale() is a shorthand function for the scaleX and scaleY functions. We will take a look at the function in detail below. For now, remember that the scale() function only scales in 2D, and if you want to scale in 3D, you should use scale3d() instead.
- skew() function tilts or leans an element to the left or right – imagine a rectangle that is skewed into a parallelogram. skew() is a shorthand that combines skewX() (skews an element in the horizontal direction) and skewY() (skews an element in the vertical direction) by accepting both of their values .
- rotate() function rotates the element from its current position. The direction is clockwise and an element rotates around a fixed point on the 2D plane. If you want to rotate an element around a fixed axis in 3D, you need to use the rotate3d() function.
- matrix() is a function that is probably too complicated to be written by hand because it combines all transforms into one.
- perspective() is a function that has no effect on the element. It’s aim is to affect the transforms of descendent elements’ 3D transforms, because it allows them all to have a consistent depth perspective.
2.1. CSS transform property and translate() function
As already said above translate() function moves an element horizontally and/or vertically, in more detail a function looks like this:
- translate(x,y) – controls a 2D movement
- translate3d(x,y,z) – controls a 3D movement
- translateX(x) – controls a movement, using only the value for the X-axis
- translateY(y) – controls a movement, using only the value for the Y-axis
- translateZ(z) – controls a 3D movement, using only the value for the Z-axis
Let’s take a look a this example:
.my-square {
transform: translate(30px, 40px);
}
In the example above we used a shorthand, but we could be also more specific and said:
.my-square {
transform: translateX(30px);
transform: translateY(40px);
}
Do you think the result would be the same? Nope. If we take this exact code, it would only move the square down, because the browser would apply the last function. transform: translateX(30px); equals to transform: translate(30px, 0px); and transform: translateY(40px); equals to transform: translate(0px, 40px);, so if you want to move an element left or right simply use the
translateX (for right movement use positive value, for left movement use negative value), or if you want to move it up or down, use translateY (positive value for down, negative value for moving up).
So, the first code above with the transform: translate() function will move our square 30px to the right, and since we provided a second value too, it will also move it 40px down. In case we would provide a negative second value, the element would move up. You will notice in a visual example below in a pen that by using the translate() function in a transform property the square is not affecting the position of text that surrounds the square – the remaining elements simply stay put, as if our pink square is a block element. As far as our layout algorithms are concerned, from Flow to Flexbox to Grid, this property has no effect.
See the Pen
translate() in transform by Tanja (@tanjatod)
on CodePen.
Maybe you’re also asking yourself – why wouldn’t we simply use top/left/bottom/right to reposition an element. Probably the latter would be best to use in layouts, while translate() would be best to apply in the context of animation. If you would like to check our tutorial about animation property, you should check this out.
Besides pixels we used in our example, we can use any other length value.
And besides that, there is also one super-powerful specific for the translate() function – we can use a percentage value! What it means is that the percentage refers to the element’s own size, not the available space within the parent container. For example, if we set the transform: translateY(-100%) that will move our square up by its exact height, no matter what that height is, to the pixel. And this “trick” is very handy when we want an element to simply sit outside another element – when we want the translated element to be out of flow – when we want to stick it like a sticker onto another element, without the entire layout recalculating. A very common example of this use would be adding a “close” button outside a dialog box.
2.2. CSS transform property and scale() function
As already said above, scale() function can change the size of the element. And the scale() also affects the size of a font, the padding, and the width and height of an element. When we want to scale only horizontally, we can use the scaleX function, and scaleY function, when we want to scale vertically.
- scale(x,y) – controls a 2D scale transformation
- scale3d(x,y,z) – controls a 3D scale transformation
- scaleX(x) – controls a scale transformation by giving a value for the X-axis
- scaleY(y) – controls a scale transformation by giving a value for the Y-axis
- scaleZ(z) – controls a 3D scale transformation by giving a value for the Z-axis
.my-element {
transform: scale(2, 4);
}
is not the same as
.my-element {
transform: scaleX(2);
transform: scaleY(4);
}
because the browser reads the last scale, in our case scaleY(). Therefore, we use scaleX and scaleY when we want to scale only in one direction, either horizontally or vertically.
And if we use just one number transform: scale(10);, the browser will read that the increase is the same in terms of X and Y axis.
It is best if we take a look at the scale() function on an example. We declared the size of an element to be 15px tall and 15px wide, but with the scale() function we increased the size 10 times. So, now the element is 150px tall and 150px wide and the size of a font increased too – at first we declared it to be 1px, but with the scale(10) we increased it to 10px, and the same happened to the padding, too. We added a simple animation to make it more obvious.
See the Pen
transform: scale() by Tanja (@tanjatod)
on CodePen.
So, it is very important to remember we are scaling up or down the entire element – not just its size and but everything that comes along with the element – all of its descendants, in our case, in addition to the size of an element, its font size, paddings, and margins. And this reveals an important truth about transforms: elements are flattened into a texture, therefore this is what makes transform such a great choice for animations. Imagine how much work would be required to change first the width of an element, and then the text inside, and the padding, and so on. All of the layout algorithms would need to run every time – where is the element, where are its children, what’s with the text, what’s with the line-wrapping algorithm, what’s with the paint algorithm. So, with the transform function we skip a bunch of these steps, the calculations are way faster and the animation is much more smooth.
2.3. CSS transform property and skew() function
skew() function is a shorthand that combines skewX() and skewY() by accepting both of their values. This function tilts or leans an element to the left or right – imagine a rectangle that is skewed into a parallelogram.
- skew(x-angle,y-angle) – controls a 2D skew transformation along the X- and the Y-axis
- skewX(angle) – controls a 2D skew transformation along the X-axis
- skewY(angle) – controls a 2D skew transformation along the Y-axis
Let’s take a look at the skew() function on the following example:
See the Pen
transform: skew() by Tanja (@tanjatod)
on CodePen.
In the example above we used the skewX(), but we could do the same with the skewY to tilt the square on the Y-axis, like so:
See the Pen
transform: skewY() by Tanja (@tanjatod)
on CodePen.
And this is how it looks when we use transform: skew() – when we tilt the square on X and Y-axis:
See the Pen
transform skew() by Tanja (@tanjatod)
on CodePen.
2.4. CSS transform property and rotate() function
When we declare rotation() it looks like we rotate an element. It rotates clockwise its original position when we apply positive values for degrees, and in the opposite direction for negative values. If we go into details, we can sum up the following:
- with rotate(angle) we define a 2D rotation, and we define the angle in the parameter
- rotate3d(x,y,z,angle) declares a 3D rotation
- rotateX(angle) specifies a 3D rotation along the X-axis
- rotateY(angle) specifies a 3D rotation along the Y-axis
- rotateZ(angle) specifies a 3D rotation along the Z-axis
The syntax looks like this:
.my-box {
transform: rotate(50deg);
}
But. When we execute transformations in general, we do not modify the element, but we affect the coordinate system an element is positioned into. So, when transforming with rotation(), we actually rotate the x and y axes. Why is it important to know we’re dealing with a rotation of a coordination system and its axis and not the rotation of an element itself? It is important if you’re applying multiple transformations to an element – in this case, we have to be careful about the order in which we declare transformations. For example, if we rotate before translating, the translation – the movement of an element will be along the new axis of rotation, and that could cause different results than we might expect.
You should remember that the following properties are always applied in the same order, and they happen before everything in the transform property:
- translate
- rotate
- skew
- scale
Here we present a rotation according to individual axis:
See the Pen
by Tanja (@tanjatod)
on CodePen.
Below we presented a super simple animation where we infinitely rotate a square for 360 degrees every five seconds:
See the Pen
transform rotate() by Tanja (@tanjatod)
on CodePen.
3. Can we add multiple values to the transform property?
Yes, we can. You simply create a space-separated list, like so:
.my-box {
width: 100px;
height: 100px;
transform: scale(10) skew(40deg);
}
However, there is one thing that needs to be mentioned again – we already talked about it in the rotation section of this article. With transformations, we’re moving the coordination system and the element itself. For this reason, it is really important to understand that there is an order in which these transforms will be carried out. For example, in the snippet above, the my-box will be tilted first (the skew() function) and then the element and all its descendants will grow 10 times (scale() function). For now, notice that the following properties are always applied in the same order, and they happen before everything in the transform property:
- translate
- rotate
- skew
- scale
4. What about matrix() transform function?
This function serves as a transform shorthand because it can combine all transform in one. The matrix() function is specified with six values. The constant values are implied and not passed as parameters; the other parameters are described in the column-major order: matrix(a, b, c, d, tx, ty), where a b c d describe the linear transformation, and tx ty describe the translation to apply.
5. What about 3D transforms?
In addition to the 2D transforms we’ve covered in this tutorial, CSS can transform elements in a third dimension, too! All of the properties listed above, except for the skew(), have 3D versions.
5.1. translate3d(x, y, z)
- translateZ(z)
- The third value in translate3d or the value in translateZ moves the element toward the viewer, negative values move the element away from the viewer.
5.2. scale3d(x, y, z)
- scaleZ(z)
- The third value in scale3d or the value in scaleZ controls the scaling along the z-axis.
5.3. rotate3d(x, y, z)
- rotateX and rotateY will rotate an element in 3D space around specified axises, but the third value in scale3d or the value in scaleZ controls the scaling along the z-axis.
- rotate3d() function specifies a point in 3D space in which to rotate the element around.
5.4. matrix3d(…)
With matrix3D() function you can programmatically describe a 3D transform in a 4×4 grid of 16 values.
5.5. perspective(value)
This function doesn’t affect the element itself, but it affects the transforms of descendent elements’ 3D transforms because it allows them to have a consistent depth perspective.
Transformations in combination with inline elements and flow layout
They do not work – transformations in combination with inline elements and flow layout – no go. You’ll have to either change the layout to either Flexbox or Grid. Or even, easier to change your display from display: inline to display: inline-block.