📓2.3: Animations

Table of Contents


New Unit! Use a GitHub Template for class notes:

  1. Go to the public template repository for our class: BWL-CS HTML/CSS/JS Template
  2. Click the button above the list of files then select Create a new repository
  3. Specify the repository name: CS1-Unit-2-Notes-Animations
  4. Click

    Now you have your own personal copy of this starter code that you can always access under the Your repositories section of GitHub!

  5. Now on your repository, click and select the Codespaces tab
  6. Click Create Codespace on main and wait for the environment to load, then you’re ready to code!
  7. 📝 Take notes in this Codespace during class, coding along with the instructor.

CSS Transforms

The transform property is a powerful tool to change the appearance of elements without affecting the natural document flow.

You have likely seen it in action on many of your favorite websites! Transforms are very commonly used for animated effects. While we are sure you’ll like to create sleek animations of your own, we first need to understand how transforms work.

image

📖 Learning goals:

  • How to use 2D transforms.
  • How to use 3D transforms.
  • How to chain multiple transforms.
  • The benefits of using the transform property.

The transform property takes in one or more CSS transform functions as its values, with those functions taking in their own value, usually an angle or a number.

element {
    transform: function(value);
}

Almost all HTML elements can have the transform property applied to it, with the exceptions being non-replaced inline elements.

“Non-replaced” refers to elements whose content is contained directly within the HTML document (<span>, <b>, and <em>, for example), as opposed to a “replaced” element’s content being contained outside of the document (<a> and <img>, for example).

2-dimensional transforms

In this section, we’ll go through 2D transforms with the following transform functions: rotate, scale, skew, and translate.

Rotate

This is the transform function value to rotate an element on a 2D plane:

.element {
  transform: rotate();
}

Below is a CodePen that shows how the value affects the target element.

See the Pen 2D Rotate | CSS Transform by TheOdinProject (@TheOdinProjectExamples) on CodePen.

Scale

These are the transform function values to scale (adjust the size of) an element on a 2D plane:

.element {
  transform: scaleX();
  transform: scaleY();
  transform: scale();
}

Below is a CodePen that shows how each value affects the target element.

See the Pen 2D Scale | CSS Transform by TheOdinProject (@TheOdinProjectExamples) on CodePen.

Skew

These are the transform function values to skew an element on a 2D plane:

.element {
  transform: skewX();
  transform: skewY();
  transform: skew();
}

Below is a CodePen that shows how each value affects the target element.

See the Pen 2D Skew | CSS Transform by TheOdinProject (@TheOdinProjectExamples) on CodePen.

Translate

These are the transform function values to translate (move) an element on a 2D plane:

.element {
  transform: translateX();
  transform: translateY();
  transform: translate();
}

Below is a CodePen that shows how each value affects the target element.

See the Pen 2D Translate | CSS Transform by TheOdinProject (@TheOdinProjectExamples) on CodePen.

Chaining multiple transforms

Now that you have a grasp of 2D transforms, we will learn how to chain them. Chaining multiple transforms is done by adding more transform functions with a space between each one. Take a look at the code below:

<div class="red-box"></div>
<div class="blue-box"></div>
.red-box,
.blue-box {
  position: absolute;
  width: 100px;
  height: 100px;
}

.red-box {
  background: red;
  transform: rotate(45deg) translate(200%);
}

.blue-box {
  background: blue;
  transform: translate(200%) rotate(45deg);
}

There are two boxes located at the same position. We chained rotate and translate function values to both boxes, but in different orders. Make a guess on what will happen to each box, then run it in a code window.

If you guessed correctly, congratulations! But this is a tricky concept. MDN’s transform docs state that “composite transforms are effectively applied in order from right to left”.

The blue box rotates 45 degrees on the spot, then translates on the X axis by 200%, moving it directly to the right. The red box translates by 200% first, so moves to the right, but the transform origin is still where it used to be. Therefore, it rotates 45 degrees around that original point, making the red box “swing down” to end up diagonally from where it started.

While you can generally chain multiple transforms in any order for various results, there is one exception: perspective. This brings us nicely to the next section where perspective is involved.

3-dimensional transforms

The rotate, scale, and translate transform functions aren’t limited to just 2D planes. They also work for 3D planes as well! However, to perceive a 3D effect on some of these function values, perspective is required.

Perspective

This is the transform function value to set the distance from the user to the z = 0 plane:

.element {
  transform: perspective();
}

Essentially, by setting a perspective value, we are telling the object to render as if we were viewing it from a specific distance on the z-axis.

Unlike other transform function values, perspective must be declared first (leftmost) when there are multiple transform function values. In the upcoming examples for rotate, scale, and translate, we will be able to see how it affects the target element.

Rotate specific axis

These are the additional transform function values to rotate an element in a 3D space:

.element {
  transform: rotateX();
  transform: rotateY();
  transform: rotateZ();
  transform: rotate3d();
}

Below is a CodePen that shows how the first three values affects the target element.

See the Pen 3D Rotate | CSS Transform by TheOdinProject (@TheOdinProjectExamples) on CodePen.

Scale specific axis

These are the additional transform function values to scale an element in a 3D space:

.element {
  transform: scaleZ();
  transform: scale3d();
}

See MDN’s 3D cube in action with scaleZ and scale3d.

Translate specific axis

These are the additional transform function values to translate an element in a 3D space:

.element {
  transform: translateZ();
  transform: translate3d();
}

translateZ doesn’t do much without perspective. Instead, perspective and translateZ work together to create the illusion of 3-dimensional distance from the rendered object, as shown in the example below.

See the Pen TranslateZ | CSS Transform by TheOdinProject (@TheOdinProjectExamples) on CodePen.

🧠 Knowledge check

The following questions are an opportunity to reflect on key topics in this lesson. If you can’t answer a question, click on it to review the material.

📚 Additional resources


CSS Animations

Now let’s explore CSS animations using keyframes. Animations let you animate elements from one style configuration to another. Once you have your elements in place and CSS defined, an animation will start running immediately if that’s what you told it to do!

📖 Learning goals:

  • How to configure animation sub-properties.
  • How to sequence an animation using @keyframes.

image

Animation sub-properties

Let’s see an animation in action to see what we’ve been talking about.

See the Pen keyframes 1 longhand by TheOdinProject (@TheOdinProjectExamples) on CodePen.

Note how the animation is already running and how it keeps repeating itself. We’ll cover that @keyframes rule at the bottom of our example in a bit, so for now focus on the actual animation properties used in the example above.

The code below is known as the configuration stage where we define animation properties to be applied on the element, and it is only the first half of defining an animation.

#ball {
  /* ... other CSS properties ... */
  animation-duration: 2s;
  animation-name: change-color;
  animation-iteration-count: infinite;
  animation-direction: alternate;
}

In our example, we have:

  • An animation-duration of two seconds. This means that it will take two seconds for the #ball element to complete one animation cycle.
  • Defined the animation-name to be “change-color” which is essential for the @keyframes section coming up next.

    This is just a custom name that is not a particular CSS value. We could have called it “pineapples” if we so wished, but for our purposes “change-color” suits us well.

  • Set the animation-iteration-count to infinite, which means this animation will run forever. You could set this to 1, 2, or as many iterations as you wish.
  • Set the animation-direction to alternate. This property decides if our animation should _alternate direction on the completio_n of one cycle, or reset to the start point and repeat itself.

    Here it means that the #ball will smoothly change back to its original color instead of “jumping” straight back to red.

Animation keyframes

Now it’s time to tackle the second half of our animation definition by exploring the @keyframes at-rule.

@keyframes change-color {
  from {
    background-color: red;
  }

  to {
    background-color: green;
  }
}

The @keyframes at-rule references the ‘change-color’ name we defined earlier. Then, we use the from and to properties to change the background-color of #ball from red to green.

It’s important to know that keyframes use a percentage to indicate the times for an animation to take place and that the from and to statements are actually aliases for 0% and 100%, respectively. You can read from/0% as meaning ‘at zero seconds’ and to/100% as ‘at 2 seconds’ according to our animation-duration in our example from above. There is no hard and fast rule on whether or not you should use from/to or 0%/100%. Just pick a style and be consistent with it!

The @keyframes at-rule also defines one animation cycle. So if we were to change our animation-iteration-count from earlier to 2 then the ball would change its background-color from red to green, then from green to red, and then the animation would stop. Be careful not to think of one iteration as a complete loop, but rather a single cycle from beginning to end (or end to beginning when alternating the direction).

Now it’s time to introduce the shorthand notation for our animation properties and glimpse a little into the added flexibility of the keyframe notation. Check out the live example below then have a look at the notation:

See the Pen keyframes 2 shorthand by TheOdinProject (@TheOdinProjectExamples) on CodePen.

#ball {
  /* ... other CSS properties ... */
  background-color: red;
  animation: 2s change-color infinite alternate;
}

@keyframes change-color {
  from {
    background-color: red;
  }
  
  50% {
    transform: scale(2);
    background-color: blue;
  }

  to {
    background-color: green;
  }
}

Here we added another keyframe for when the animation-duration is at 50%, or 1 second. This means as well as the background-color changing to an additional value, we have also specified that the ball double in size. Just be aware that additional keyframes are always defined in percentages. Only the 0%/100% values may use the from/to alias.

Hopefully, this gives you a glimpse into the power the @keyframes syntax provides to you when it comes to controlling the animation of an element’s properties. You can add keyframes whenever you want, control whatever CSS-animatable properties you want, and have the control to add some real creative flair to your website elements.

🧠 Knowledge check

The following questions are an opportunity to reflect on key topics in this lesson. If you can’t answer a question, click on it to review the material.

📚 Additional resources


Acknowledgement

Content on this page is adapted from The Odin Project and most images are from Interneting is Hard.