Introduction to CSS Animations
In this tutorial, we're going to walk through how we can implement animations in HTML and CSS.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
  • Complete the Exercise
Video locked
This video is viewable to users with a free Dev Camp account

Now, let's look at what we're going to be implementing first. Right here in this little navbar, if I hover over any of these links, do you see how the letters kind of spread out and the color changes? Also, there's a smooth kind of easing in and easing out as I hover over?

large

Each one of these is something in CSS that we have control over. First, we have control over what is called a pseudo-element, which is also referred to as a hover state. When I hover over one of these items, that gives a little trigger to CSS that we can use.

We can listen for that kind of an event and then what we can do is make some changes to the styles. We can do things like change the letter spacing, change the color, and then we can add an animation so that it all happens really nice and smooth.

Right now, we just have a basic set of links here. What we're going to walk through is how we can animate these and implement that type of behavior. I'm going to switch back to the text editor here.

We have our links-wrapper, and if you look at the HTML structure, we have the links-wrapper, the inside of the links-wrapper, and we have the four child-nav-links. So, we want to work with this nav-link class right here.

large

The very first thing we want to do is, let's just test to make sure we have access to that value. I'm going to say links-wrapper, and then I'm going to grab the nav-link. Then, I just want to grab the a, that is the a-tag. So I'm grabbing the link itself right here.

Let's make sure that we have access to it by being able to remove that underline, to customize the font, and to do some things like that.

I'm going to say, font-family here, and then I want to use the Ubuntu Condensed, and then have a backup of sans-serif. Let's go with a custom color here. We'll say #CBCBCB for the hexadecimal value, giving us that nice little light gray.

styles.css

.links-wrapper > .nav-link a {
    font-family: "Ubuntu Condensed", sans-serif;
    color: #CBCBCB;
}

The way we can remove the underline is by saying text-decoration: none. Then I'm going to put something here that is going to be required in order to have that nice smooth animation.

What we're going to say is, not transform, but transition. Then transition takes a few arguments, but for right now we can just pass in the amount of time we want the transition to take place over. I want it to take 0.5s. That is going to work well.

styles.css

.links-wrapper > .nav-link a {
    font-family: "Ubuntu Condensed", sans-serif;
    color: #CBCBCB;
    text-decoration: none;
    transition: 0.5s;
}

Now, whenever one of those hover effects is triggered, what this transition does is it's a rule that says, "If any kind of action takes place, then we want to have a smooth transition that should take half a second to get to that next state."

Let's save this, and if we hit refresh, you can see that we now have the new font. We don't have the animations yet, but it removed the underline. So, that is working well.

large

Now, let's come up here and I'm going to just copy this selector. Then, we're going to update it a little bit. Instead of just grabbing the nav-link and the a-tag, we're going to say, a:hover.

styles.css

.links-wrapper > .nav-link a {
    font-family: "Ubuntu Condensed", sans-serif;
    color: #CBCBCB;
    text-decoration: none;
    transition: 0.5s;
}

.links-wrapper > .nav-link a:hover {

}

What hover is, it is a pseudo-state. This is a pseudo-selector, meaning that we're not technically grabbing an element. We're saying that "Whenever a hover event takes place, I want you to change the value to whatever we pass inside of these curly braces."

Right here, I want to change the color. We're going to use that gold color. I have that at, #CEA135, and then let's also add that space between the letters. The way we can do that is with a rule called letter-spacing, and I want to add 2px of spacing between those letters.

styles.css

.links-wrapper > .nav-link a {
    font-family: "Ubuntu Condensed", sans-serif;
    color: #CBCBCB;
    text-decoration: none;
    transition: 0.5s;
}

.links-wrapper > .nav-link a:hover {
    color: #cea135;
    letter-spacing: 2px;
}

Let's switch back. Hit refresh, and now, if we hover over, you can see we're getting that nice hover effect. That is working really well.

large

If you're ever curious about some of the states, let me go and select one of these items. If you're ever curious about, say, the hover state. If you come here to the Chrome developer tools and click on hover, you can see that you have access to view what they look like in one of these states.

large

It also gives you a nice hint of telling you some of the other pseudo-state selector names. Right here, if you click on hover, you can see what happens when you hover over, even without having to go and perform the action by yourself.

That's a nice little helpful tool whenever you're trying to test out some of your pseudo-selectors. Now, we're not quite done. If you notice when I hover over, do you see how this actually moves the other elements slightly?

That's because each one of these items is dynamic. We're using Flexbox for the spacing. Whenever I hover over one of these items, it is actually shrinking the space for each one of the other elements. That's the reason why that is occurring.

What we can do is we can actually give a hard-coded defined width for each one of these items. I'm going to open up the code again and I'm going to work with this nav-link wrapper because each one of those a-tags is wrapped up inside of that nav-link div.

I'm going to remove the a-tag, and now what I can do is, I'll just say width and let's set it at 70px. That's not going to give us exactly what we want, and I'll show you why here in a second.

styles.css

.links-wrapper > .nav-link {
    width: 70px;
}

.links-wrapper > .nav-link a {
    font-family: "Ubuntu Condensed", sans-serif;
    color: #CBCBCB;
    text-decoration: none;
    transition: 0.5s;
}

If I hit refresh, you see how they move slightly to the left? We fixed our issue with how it's not pushing the items anymore. The reason why is if you click on one of these nav-links, do you see where it shows, right there, how the div is now a little bit wider than it was before?

large

Before we had this width, if you'd hover over and inspect that item, the full width just was whatever the width of the content was. When you set this 70px, you're creating a container so that you can make sure that it doesn't spill over. So, the letter spacing is not going to spread that item past that 70px.

Now, if you are working with a navigation bar or you're building this feature and you have some elements that maybe have wider names or something, then 70px won't work. You might have to do 100px or something like that.

The reason why all of these items are to the left is because now, with these 70px, all of the text elements are text-aligned to the left. We can fix that if you just say text-align inside of this wrapper, and say text-align: center.

Now, do you see how those are all perfectly centered? Now when I hover over, they spread out to the left and right because they are aligned to the center. So, let's go change that in the code. So I'll say:

styles.css

.links-wrapper > .nav-link {
    width: 70px;
    text-align: center;
}

.links-wrapper > .nav-link a {
    font-family: "Ubuntu Condensed", sans-serif;
    color: #CBCBCB;
    text-decoration: none;
    transition: 0.5s;
}

Hit save, hit refresh, and now we should have the final version of this navbar. As I hover over, each one of these works. The animations work perfectly. We've also wrapped them up in the right kind of format so that they don't get distorted whenever you're creating that hover effect.

large

Great job if you went through that tutorial. You now know how to work with animations, transitions, how to work with pseudo-classes, and also how to align text inside of wrapper divs.