How To Use the CSS Transform Property
Brittan McGinnis
Posted on May 8, 2018
How To Use the CSS Transform Property
I’m setting out to learn CSS animations and the transform
property was the second piece on my list.
My goal of this post is to teach (so that I can better learn), the very basics of transform
.
This property is super cool and was actually pretty fun to learn. I would suggest playing around with it if you are not familiar.
Basics
You should have a basic understanding of CSS and HTML prior to reading this article.
Introduction
This journey that I’m on to learn CSS animations has a super important learning element to it. I basically find and filter information pertaining to this concept. Make a list of learning comprehensions that need to be understood before I can say I “know” the thing. Do those things, be it reading articles, doing exercises, watching videos, reading books, etc. one by one. Then I play around. I have no set goal when doing this. Just to play in the most basic sense. Break stuff. Have fun. Mostly this step is to develop questions. Then research and answer my questions. Then teach. That could be a blog post, teaching a friend or just explaining in depth the concept.
During this post I may gloss over some other concepts. This post is mainly just for the CSS transform
property. However, I will be using the transition
property quite a bit as well. If you would like to read further on that, I have another blog post for that.
Transforms
CSS transform
has 6 main property values:
- scale
- translate
- rotate
- skew
- perspective
- matrix
In truth it has way more, because many of those values have an X, Y and Z property. For the sake of brevity though, I will not display that entire list. If you would like to take a look, you can see it [here].
I’ll explain below what each one of the values does.
Lets play with these
Below, I’ll build 7 examples cards. Each will perform the animation that it’s named.
Starter Code
<div class="container">
<div class="translate">
<p>translate</p>
</div>
</div>
@import url(https://fonts.googleapis.com/css?family=Open+Sans);
body {
background: lightblue;
font-family: 'Open Sans';
}
.translate {
margin: 50px auto;
background: papayawhip;
width: 150px;
height: 150px;
border-radius: 20px;
}
p {
margin-top: 60px;
}
Adds hover psuedo class
This moves the element down the Y axix 100px. While kinda cool and useful depending on your use case, it is not very graceful and does not animate very nicely. Next we'll add a transition
to make this animate smoothly.
// ...
.translate:hover {
transform: translateY(100px);
}
// ...
.translate {
// ...
transition: 1s ease;
}
.translate:hover {
transform: translateY(100px);
}
Scale
Add a duplicate of the previous div and name the class to the property that we will be changing.
I will not include this code for the following examples as it is the same.
<div class="container">
<div class="translate">
<p>translate</p>
</div>
<div class="scale">
<p>scale</p>
</div>
</div>
Here we'll add a text-align
center
to the .container
so the elements will be in the center of this container.
Then we'll change the margin
and display
properties so they sit next to each other.
// ...
.container {
text-align: center;
}
.translate, .scale {
margin: 50px 10px auto;
display: inline-block;
background: papayawhip;
width: 150px;
height: 150px;
border-radius: 20px;
transition: 1s ease;
}
p {
margin-top: 60px;
}
// ...
Then we'll add a scale
property on hover. This will shrink it to 1/2 of it's original size. Because I only provide one value it uses that value for both the x and y coordinates.
// ...
.scale:hover {
transform: scale(.5);
}
If I provide it a second value then it will apply the value to the x and y coordinates respectively.
// ...
.scale:hover {
transform: scale(.5, 2);
}
Rotate
After you have duplicated the html and renamed the class and inner text for the p tag to rotate, then add the rotate class to our base styling for our divs like so:
.translate, .scale, .rotate {
Then we'll add an :active
psuedo class to the .rotate
class. This way when we click on that element it rotates.
The rotate
value takes a turn value or a degree value.
rotate
takes a negative or positive value. If you were to give this transform: rotate(-360deg)
for example it would turn counter-clockwise
// ...
.rotate:active {
transform: rotate(360deg);
}
// This accomplishes the same thing as above
.rotate:active {
transform: rotate(1turn);
}
Skew
The skew
value will 'tilt' the element to one side depending on the value given. As with many of these functions you can specify either scaleX
, scaleY
or scale
. If you pass in only one value to scale()
it will give the Y axis a 0 value which will then only scale the X axis.
The skew
value also takes degree values, turns or radius as parameters. This signature looks like this: skew(10deg)
or skew(-0.06turn, 18deg)
or skew(.312rad)
. Taken from the MDN docs
Skew can be a little tricky because you may only want to skew the container of an element and not the inner content. In that case you will have to skew in reverse.
Below you can see an example of skewing the div but keeping the text inside un-skewed.
- We'll duplicate our html, change our class name and our inner text like so
<p>skew</p>
- We'll add
.skew
to our growing list of elements targeted in our base CSS
Now we'll add a skew value to this element.
// ...
.skew:hover {
transform: skew(10deg)
}
Problem with this is that it skews the inner text as well. We can remedy that by giving it an inverse value of the same amount and targeting that element.
.skew:hover p {
transform: skew(-10deg);
}
This is still kind of weird looking because the text corrects itself on hover. I'm not sure if there is a more natural way to fix this. I couldn't come up with one in this contrived example. If any reader has a better way please let me know in the comments.
Perspective
The perspective
value is used to give some perspective to 3d elements. You are targeting the z-index so that it looks as thought the element is popping out of the page. The point that the perspective originates from is the center. You can alter this using the perspective-origin
value. I will however use the transform-origin
property because I am using this on the transform property and on the perspective property.
For this example I will use both the perspective
and the transform-origin
values. I'll make it look as though the card is flipping up and out from the bottom.
Copy the code from the last example and add the respective class and supporting css.
Then add this to the hover state.
// ...
.perspective {
transform-origin: top;
}
.perspective:hover {
transform: perspective(300px) rotateX(50deg);
}
Matrix
The matrix
function is a little more complex and admittedly the one that I spent the least amount of time playing with. Also it requires that you have a pretty good understanding of linear algebra and the Cartesian coordinates system (which I do not), in order to really understand what is going on.
There is both a matrix
and a matrix3d
function. The matrix
function is behind every transform function. For example, when you are calling rotateX(30deg)
, you are actually saying matrix(0.86602540, 0.50000000, -0.50000000, 0.86602540, 0, 0);
. There is a cool matrix calculator for rotate
here, where you can see the value of your rotation.
2d transforms are a 3x3 matrix of integers where 3d transforms are a 4x4 matrix. Hence the arguments passed to each function respectively.
Big thanks to this deep dive article Understanding the CSS Transforms Matrix by Tiffany Brown.
Here I'll make this card flip up and out to the left using the matrix
function.
We'll add our html and css same as with the previous cards, then you can add this :hover
state to the .matrix
class
// ...
.matrix:hover {
transform: matrix(.5, -1, 0, .5, 0, 0);
}
The matrix3d
can create the illusion of 3 dimensions in 2 dimensions using CSS. The signature takes 16 arguments as coordinates.
I'll copy all the stuff I just did for Matrix and just add 3d to the class name and text. Then we'll rotate this card up, right and out at the bottom using the matrix3d
function. We'll do this on the :active
psuedo class.
// ...
.matrix3d:active {
transform: matrix3d(0.8535533905932737, 0.4999999999999999, 0.14644660940672619, 0, -0.4999999999999999, 0.7071067811865476, 0.4999999999999999, 0, 0.14644660940672619, -0.4999999999999999, 0.8535533905932737, 0, 22.62994231491119, -20.3223304703363, 101.3700576850888, 1);
}
Below is a pen of all these examples.
Conclusion
I would love to hear any feedback that anyone has about my understanding of the transform
property. I wrote this post to re-enforce my knowledge of this concept. If I have made any glaring errors please let me know. I will gladly update this post with the correct information.
This is a Cross Post from Medium
Posted on May 8, 2018
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.