The Basics of Animation in CSS: Rotating and Scaling
Published: 2023-07-26 15:33:41

Animations in websites can be done in many ways. From coding it in vanilla Javascript, to the countless libraries you can download, to Flash (rip), you can pick and choose what you use to fit your needs. But one basic way to do so is in CSS. This is useful since they are natively supported by all the major browsers and don't require any extra downloads. In this post, we will show how to rotate and scale in multiple dimensions.

## Setting the Stage
_note: this will be done in SCSS_
First, we need to set up the objects we want to animate. We will create 3 axes, and a circle at the center, all as `div`s. We'll wraps them in a single parent "scene" `div`. This will be all the HTML we'll need for this. So far, our code is:
```
<div class='scene'>
  <div class="axis x"></div>
  <div class="axis y"></div>
  <div class="axis z"></div>
  <div class='circle'></div>
</div>
```
However, if you look at this in the browser, you'll see nothing. So now, we need to add some basic properties to our `div`s. 
For our `body`, let's set the `background-color` to black, `display` to grid, `place-items` to center, `min-height` to 100vh (100% of the viewport size), and `overflow` to hidden.
For our `scene` div, we just need to set the `position` to relative.
For our 3 `axis` divs, we'll give them a `height` of 1px (1 pixel), a `width` of 200vh (twice the size of the viewport), a `left` of -100vh (to center them), and `position` to absolute. We'll also give each axis their own color, using the `x`, `y`, and `z` classes. We will also `rotate` `y` by 90deg around the z-axis, and the `z` by 90deg around the y axis.
Lastly, we'll give the `circle` div a `position` of absolute, `border-radius` of 50% (which will make it a circle), a `width` and `height` of 120px, a `left` and `top` of -60px (to center it), and a `background` of white.
So far, it should look like:
{% embed https://jsfiddle.net/MarcKatz/nt2xecw7/2/ %}

## Starting the animations: Rotating the scene
Let's start by animating the entire scene, so it is if we are orbiting the circle. First, we have to set the `perspective` of the `body` to 800px, so the "camera" will be 800px from the center. We will also add 
```
  *:not(:empty){
    transform-style: preserve-3d;
  }
```
to the `body` which will allow us to see things in 3 dimensions.
Next, let's add an initial rotation around the x-axis by adding `transform: rotateX(10deg);`.
Since we are rotating the whole scene, we will give the `animation` to the `scene` div. Our `animation` will take 4 inputs: a name, a duration, an iteration number, and a timing function. Let's call this animation "orbit", have it last 20 seconds, repeat `infinite`ly, and with a `linear` timing function. So far, it should look like `animation: orbit 20s infinite linear;`
Next, we have to create the `keyframes`. Each `keyframe` will specify how far we want the rotation to go. Luckily, we only need two `keyframes`. The first will be at 0%, where we will give it a `transform` of `rotateY(0)`. This is the starting position. At 100%, we want it to make a full rotation, so we can set another `keyframe` at 100%, and give it a `transform` of `rotateY(360deg)`. We will also have to add the `rotateX(10deg)` in each transform, in order to keep that constant.
Now, the animation will look like:
{% embed https://jsfiddle.net/MarcKatz/n47zhrLu/7/ %}

##Rotating the Circle
Now, let's add an animation to the circle, so it rolls while clicked. First, we have to add the animation to the '.circle' div. Here, we will use `animation: roll 5s infinite linear;`. We will also use very similar `keyframes` as the scene, but with `rotateX` instead of `rotateY`. If you look at the code now, you'll see that the circle is rotating around the x-axis. However, we only want it to do so while clicked. So in `.circle.`, we will add `animation-play-state: paused;`. This will set the default state of the circle's animation to not run. Now, we'll add a new section, for `.circle:active`. This will be applied while the `.circle` div is being clicked. In here, we will add `animation-play-state: running;`, making the animation run.
Now, it will be:
{% embed https://jsfiddle.net/MarcKatz/nxkmepv1/10/ %}

##Scaling the Circle
Lastly, let's add another animation to the circle. 
Firstly, if we just add another animation, it will override the transitions that we already wrote. So let's first wrap our `circle` div in a new `squish` div.
Next, we will make it stretch horizontally, then return to normal, then stretch vertically, and then return to normal. Again, we will have to add an animation to `.circle`. We will add `, squish 20s infinite linear` to our `animation` property in `.circle`. We will also have to add `, running` to the `animation-play-state` property, so it will run by default. Now, the `keyframes` will be more difficult. First, we'll set the `keyframes` that will be the default values. This will happen at 0%, 50%, and 100%. So we will add a `keyframe` of `0%, 50%, 100% { transform: scale(1); }`. Next, at 25%, we want to have a `transform` of `scaleX(4)`, which will make it four times as long. Finally, at 75%, we want a `transform` of `scaleX(4)` to make it 4 times as tall.
Our final product will be:
{% embed https://jsfiddle.net/MarcKatz/061xpu45/53/ %}

#Final thoughts
Congrats! This is the first step towards understanding animations in CSS. There are many other operations you can do to make even more complicated animations, and there are some really impressive examples out there. Keep playing around with it make it even cooler!