Transitions aren’t just for adding pretty flair to your app. A good transition can be the difference between a user signing up, making a purchase, or completely leaving your website. For example, Amazon found that it cost them about 1% in sales for every 100ms of latency.
You can mitigate the risk of users leaving your site with a good transition. The way Vue.js handles transitions and animations makes it super easy to add them to your application.
In this post we’re going to focus on the fundamentals of how Vue.js handles CSS transitions. With this knowledge you’ll be able to start creating your own transitions. Once you have the fundamentals down, you can quickly go on to master the full power of Vue’s transition and animation capabilities.
Transitions vs. Animations
Let’s explore the differences between transitions and animations before we dive in.
A transition is when an element goes from A to B. They are limited to two stages: going from the start state (A) to the end state (B). They work really well for things like hovering over links and buttons, or adding a new item to a list. The main purpose of transitions is to create a natural demonstration that something has changed. A good example of a transition in the real world would be automatic doors. They start closed and when you step in front of them, they automatically transition into the open state.
Here’s an example of a simple transition from Stripe’s homepage.
Animations, on the other hand, can have many in-between states known as keyframes. They can go from A to B to C to D and beyond. They are useful for things like a loading spinner or an audio visualizer. Their main purpose is to continuously showcase that something is changing. They can have ending states, but unlike transitions they’re not limited to two states. In nature, a whirlpool would be an example of an animation. It’s continuously in a changing and whirling state, but it might come to an end eventually.
In a way, animations are just super transitions because they add more in-between states. While transitions only go from A to B, animations can have as many in-between states as necessary. After understanding the fundamentals of transitions, making the jump to animations is an easy step.
In this post, we’ll focus exclusively on transitions and how to create the menu hover transition from the Stripe example above.
We’ll start with the following HTML:
The Transition Element
Vue.js has a wrapper
In the case of CSS transitions, the
<transition> element takes care of applying and unapplying classes. All you have to do is define how you want the element to look during the transition.
It acts like any other Vue.js component, and you can use the same directives on it like
For our menu popover element we can wrap the menu popover markup with this
<transition> element and give it a name.
The transition element applies six classes to your markup that you can use to separately handle your enter and leave transitions. There are three classes to handle the A to B transition for when the element is displayed, and another three to handle the A to B transition for when the element is removed.
The enter transition happens when the component is being enabled, or displayed. Those classes are:
The leave transition is when the component is being disabled, or removed. Those classes are:
v- prefix is the default when you use a
<transition> element with no name. In our case since we named the transition menu-popover, the
v-enter class would instead be
In the case of the menu popover, the enter transition would be when the user initially hovers over the menu.
v-enter is the class you use to define what that A part of a transition is. In other words, it defines the starting styles of the transition.
v-enter-to is the class you use to define the B part or the ending styles of the transition.
v-enter-active is the class that helps you define how to go from A to B. So this is where things like duration and easing functions go.
Before you hover over the menu popover, its starting state is invisible. It also has a slight rotateY transform effect applied to it, and then it flips in. This class looks like the following:
After you’ve hovered on the menu popover, its ending state is completely visible and it’s not transformed. That ending transition looks like the following:
Here is where you can apply the styles that handle how that transition will happen. In Stripe’s case, it’s a fairly fast transition that happens in about 200ms and it animates both the opacity and the transform at the same time. It also appears to have a slight ease-out animation.
We can define all of that inside of this animation here:
transition: opacity, transform 200ms ease-out;
The leave transition of the menu popover is when the user hovers out of the menu and the transition element hides. It is an entirely separate transition from the enter transition.
Easily creating inverse transitions
For 90% of cases, the way something transitions out is just the inverse of the way it transitions in, but it’s still a separate transition. One transition for when it enters the screen (you hover over the menu) and another transition for when it leaves (you hover off the menu).
In order to make that happen with the menu popover, we’d just make sure that the
v-leave class is the same as the
v-enter-to class so that the leave transitions starts where the enter transition ended.
v-leave-to would be the same as the v-enter class so that it ends where it started.
Finally, we’d make sure that the
v-enter-active and the
v-leave-active classes are the same so that both transitions have the same speed.
transition: opacity, transform 200ms ease-out;
Building on top of the fundamentals
For more in-depth information on how Vue handles CSS transitions and all the intricacies of the transition element visit the transitions guide on the Vue.js Documentation.
Vue Mastery covers transitions and animations in more depth in our Animating Vue course. Check it out!