How to Create Transitions and Animations Using CSS

Eric Hu
Level Up Coding
Published in
9 min readOct 17, 2023

--

Transitions and animations allow you to create dynamic and responsive webpages. They can help capture your audience’s attention and make your website stand out from the competition. In this tutorial, we will delve into these topics and discuss how to create eye-catching transitions and animations using CSS.

📧 Subscribe to my newsletter: https://ericsdevblog.ck.page/profile

The pseudo-selectors

Before we start, we must discuss a fundamental concept, the pseudo-selectors. The pseudo-selectors allow you to define properties that only activate when the element is under a particular state. For instance, let’s consider the <a> element, which represents a hyperlink in a webpage. Initially, it appears blue. Once clicked, it turns red, and after being visited, it turns purple. Despite being the same element, different styles are applied to it depending on its state.

The pseudo-selectors are the key to achieving this effect. They target elements only when they are in specific states. The hyperlink element starts without any state. When you move the cursor over it, it is given the :hover state, and when clicked, it acquires the :active state. Lastly, after being visited, it is given the :visited state. These states allow you to apply different styles to the same element under different circumstances. This feature is crucial for frontend design because it enables the webpage to respond dynamically to user actions.

As an example, with the following setup, the <div> will grow when the cursor is hovered on top of it.

div {
. . .
color: darkviolet;
width: 200px;
}

div:hover {
color: white;
background-color: darkviolet;
width: 400px;
}

CSS transitions

However, notice that the change happens instantly, so what if you want to customize it to make the change smoother? This effect can be achieved by defining the transition properties.

div {
. . .
transition-property: width;
transition-duration: 2s;
}

The transition-property specifies the name of the CSS property for which this transition configuration is created. And the transition-duration determines how long it takes for the transition effect to complete. In this case, the width of the <div> element will take 2 seconds to change from 200px to 400px.

You can also specify multiple transition properties like this:

div {
. . .
transition-property: width, color, background-color;
transition-duration: 2s;
}

Currently, all the transitions are linear, meaning the speed of changes remains constant throughout the transition process. You can customize this behavior using the transition-timing-function property. Some common values include:

  • linear

This is the default behavior. The transition speed remains constant from start to end, as we’ve demonstrated before. This option is equivalent to using a cubic-bezier() function with values cubic-bezier(0,0,1,1).

div {
. . .

transition-property: width, color, background-color;
transition-duration: 2s;
transition-timing-function: linear;
/* transition-timing-function: cubic-bezier(0,0,1,1); */
}

The function defines a Cubic Bezier curve. I’ll spare you the complex mathematical definition, which looks like this:

Instead, all you need to know is that this curve is defined by four control points:

With these four control points in the above example, the transition will start slow, accelerate in the middle, and finish slowly. You don’t need to know precisely how to calculate these points. You can easily find the desired control points using this website.

  • ease

Corresponds to the Cubic Bezier function cubic-bezier(0.25,0.1,0.25,1).

The transition will begin slowly, fast in the middle, and finish slowly.

  • ease-in

Corresponds to the Cubic Bezier function cubic-bezier(0.42,0,1,1).

The transition will begin slowly and then accelerate.

  • ease-out

Corresponds to the Cubic Bezier function cubic-bezier(0,0,0.58,1).

  • The transition will begin fast and then decelerate to end slowly.
  • ease-in-out

Corresponds to the Cubic Bezier function cubic-bezier(0.42,0,0.58,1).

The transition will begin slowly, accelerate in the middle, and finish slowly. This is very similar to ease, but as you can see from the curve, it is much smoother, which means there won't be a noticeable acceleration or deceleration phase.

  • step-start

This transition is a bit different. It is defined by a stepping function, steps(), which takes two values. The first one specifies the number of steps, and the second one sets the point at which the change occurs within the step, either start or end. For example:

div {
. . .

transition-property: width, color, background-color;
transition-duration: 2s;
transition-timing-function: steps(5, start);
}

In this case, the transition will take five steps, and the change happens at the start of each step.

The step-start option corresponds to the function steps(1, start).

  • step-end

The step-end option corresponds to the function steps(1, end).

You can also set a delay for the transition using the transition-delay property.

div {
. . .

transition-property: width, color, background-color;
transition-duration: 2s;
transition-timing-function: ease-in-out;
transition-delay: 1s;
}

Notice that the transition only starts one second after the cursor is hovered over the <div> element.

Lastly, CSS also provides a shorthand property that enables you to define all transition properties together. The shorthand has the following syntax:

transition: <property> <duration> <timing_function> <delay>;
div {
. . .
transition: width 2s ease-in-out 1s;
}

You can also define multiple transitions using the transition shorthand by dividing different cases with commas:

div {
. . .
transition: width 2s ease-in-out 1s,
color 2s ease-in-out 1s,
background-color 2s ease-in-out 1s;
}

CSS animations

Besides the transitions, there is also a similar concept called animation, except that you don’t need to use the pseudo-selectors to define a trigger. The animation starts automatically once it is loaded. Instead, you will need to define keyframes using the @keyframes rule.

@keyframes change-bg-color {
from {
background-color: white;
}
to {
background-color: darkviolet;
}
}

This animation is named change-bg-color, and it changes the background-color property from white to darkviolet. To employ this animation, you must specify the animation-name and animation-duration properties.

div {
. . .

animation-name: change-bg-color;
animation-duration: 4s;
}

Instead of the keywords from and to, it is possible to use percentage values, which allows you to define more than two keyframes.

@keyframes change-bg-color {
0% {
background-color: white;
}
25% {
background-color: bisque;
}
50% {
background-color: crimson;
}
100% {
background-color: darkviolet;
}
}

Just like transitions, animation also has properties animation-timing-function and animation-delay. And they work the same as their transition counterparts.

div {
. . .

animation-name: change-bg-color;
animation-duration: 4s;

animation-timing-function: ease-in-out;
animation-delay: 2s;
}

You can also define how many times you wish the animation to be repeated using the animation-iteration-count property.

div {
. . .
animation-name: change-bg-color;
animation-duration: 4s;
animation-timing-function: ease-in-out;
animation-delay: 2s;
animation-iteration-count: 3;
}

The animation-direction property defines how the animation will be played, which accepts four different options:

  • normal: The animation is played forward.
  • reverse: The animation is played backward.
  • alternate: The animation is played forward first, then backward. Only works when animation-iteration-count is more than 1.
  • alternate-reverse: The animation is played backward first, then forward.
div {
. . .
animation-name: change-bg-color;
animation-duration: 4s;
animation-timing-function: ease-in-out;
animation-delay: 2s;
animation-iteration-count: 4;
animation-direction: alternate;
}

Lastly, the animation-fill-mode property determines how the element will be displayed before and after the animation is played. By default, the element will not retain any styles from the animation.

@keyframes change-bg-color {
0% {
background-color: white;
}
25% {
background-color: bisque;
}
50% {
background-color: crimson;
}
100% {
background-color: darkviolet;
}
}

div {
. . .
background-color: aqua;
animation-name: change-bg-color;
animation-duration: 4s;
animation-fill-mode: none;
}

When set to forwards, the element will retain the styles from the last keyframe of the animation after the animation is played.

When set to backwards, the element will take on the styles from the first keyframe of the animation as soon as the animation is played.

When set to both, the element will retain the styles from the first keyframe before the animation starts (behaves like backwards), and it will also retain the styles from the last keyframe after the animation is finished (like forwards).

Lastly, just like with the transitions, CSS also offers a shorthand property called animation, which has the following syntax:

animation: <animation_name> <animation_duration> <animation_timing_function> <animation_delay> <animation_iteration_count> <animation_direction>;
div {
. . .
animation: change-bg-color 4s ease-in-out 2s 4 alternate;
}

Next steps

In this tutorial, we covered the basics of creating transitions and animations using CSS.

If you are interested, here are some of my other articles about CSS and frontend design:

This article is part of the course “HTML & CSS: A Practical Guide”.

--

--