Image

animating-vue

9 min read
Last update: December 19, 2021

Transitions

Now that we understand the value of animating our interfaces, we’re almost ready to start coding. But first, we need to understand how Vue’s transition component works, then we’ll build our first simple transition animation.


Vue Transitions

Before we begin, it’s worth mentioning that depending on whom you ask, they might say that transitions and animations are categorically different things. But for the sake of this course, we’ll consider a transition to be a simple animation.

A transition is exactly what it sounds like. It’s when something transitions from _____ to _____. From off the screen to on, from here to there, from open to closed, from visible to invisible, and so on. As such, transitions can provide the user visual feedback about how something is changing.

In Vue, we use the built-in transition component, which serves as a wrapper that gives us classes we can hook into during the lifecycle of the transition. Let’s explore how we harness those classes to define entering and leaving transitions.

Default Style

When designing a transition with Vue’s transition component, we’ll first want to ask ourselves this question: What should the default style be? In other words, how should the element/component appear when it is not transitioning?

To make this more clear, let’s look at a simple example, where we want a box to transition on and off the screen and fade its visibility as it transitions.

What should its default style be? How should it appear when it is not transitioning? In this case, we’d want it to be opacity: 1 by default because that is the style we are transitioning to and away from as the visibility fades in and fades out.

You may be aware that an HTML element’s default style is already opacity: 1 So in this case, we don’t need to define a default style for the element we are transitioning, since opacity: 1 is already defined for us by the browser. Actually, in the majority of cases you won’t need to define the default style because that style is already how the element will appear. Imagine if you were transitioning an element’s scale from 10% to 100% An element’s scale is already 100% by default, so we wouldn’t need to bother explicitly defining that again.

There are caveats to this, where we need to set a default style that is different from how the browser would style the element by default, but we’ll get to that later.

Once we are clear on what the element (or component’s) default style is, we can then make use of the transition component’s built-in classes to design the transition to and away from that default style. In other words: we can build our entering and leaving transitions.

Entering Transition

The next question we ought to ask ourselves when designing a transition is: What should the starting style be?

Since we want the square to go from invisible to visible, we’ll need it to start at opacity: 0. We put that style inside of the v-enter class, to set the transition’s starting style.

.v-enter { /* starting style */
opacity: 0;
}

Now, when the element enters the DOM, it will start off completely invisible and then transition away from that style (0) and towards our default style (1). This brings us to the next question we should ask ourselves when defining a transition: What should the active style be?

In this case, we need to know: How long should the transition take? Should we speed up or slow down the transition during the course of the transition? We use the v-enter-active class to define the behavior of the transition while it is active, while it is happening, specifying things like its duration and easing. If easing functions are new to you, you can learn more about them here.

.v-enter { /* starting style */
opacity: 0;
}

.v-enter-active { /* active entering style */
transition: opacity 2s ease-in;
}

Here, we’ve specified that we are transitioning the opacity property and set the duration of the transition to last 2s and gave it an [ease-in](https://cubic-bezier.com/#.42,0,1,1) curve, meaning it will fade in slowly then get faster as it approaches 1.

Leaving Transition

Now that our box is on the screen, how do we transition if off? In the entering transition, we needed to define the starting state, which was opacity: 0 For the leaving transition, we need to define the ending state, which brings us to the next question: What should the ending style be?

Since we are transitioning away from visible (1)and going towards invisible (0), we’d set that ending style in the v-leave-to class.

.v-enter { /* starting style */
opacity: 0;
}

.v-enter-active { /* active entering style */
transition: opacity 2s ease-in;
}

.v-leave-to { /* ending style */
opacity: 0;
}

Now, the box will transition away from the default state of 1 to our ending state of 0. And this brings us to the final major question we need to ask ourselves when defining a transition: What should the active leaving style be?

Similar to the entering transition, we define this in the v-leave-active class, setting its duration, easing, etc.

.v-enter { /* starting style */
opacity: 0;
}

.v-enter-active { /* active entering style */
transition: opacity 2s ease-in;
}

.v-leave-active { /* active leaving style */
transition: opacity 2s ease-out;
}

.v-leave-to { /* ending style */
opacity: 0;
}

Now that we understand the mechanics of a Vue’s transition classes, let’s use Vue’s transition component to build our first practical transition.


To Follow Along

You can download the starting code in the Lesson Resources on this page to follow along. Just remember to run npm install to get all the dependencies.


A Simple Transition

Whenever something abruptly pops into the DOM, it can be a bit disorienting to our user and they may not immediately know what changed on the screen. A simple fix for this is to fade the element into view over time to provide them context about what is changing. Let’s take the concepts from our opacity example from earlier and implement a simple fade transition in our example app.

Let’s say we have a modal. It could be a login modal, a configuration modal, etc. When a ****button is clicked, the modal fades in. Then the modal itself has button, and when that is clicked, the modal fades away.

Our starting template looks like:

src/views/Home.vue

<template>
    <div>
        <button @click="toggleModal">Open</button>

        <div v-if="isOpen" class="modal">
            <button @click="toggleModal">Close</button>
        </div>

    </div>
</template>

And the script section looks like:

src/views/Home.vue

<script>
    export default {
        data() {
            return {
                isOpen: false
            }
        },
        methods: {
            toggleModal() {
                this.isOpen = !this.isOpen
            }
        }
    }
</script>

We have an isOpen data property, which we toggle between true and false when the toggleModal method is run. Because we have v-if="isOpen" on our modal div, the modal will appear and disappear whenever the open and close buttons are pressed.

By wrapping the modal in a transition component, we can then create a transition for it as it opens and closes.

src/views/Home.vue

<template>
    <div>
        <button @click="toggleModal">Open</button>

        <transition name="fade"> // <-- named transition <div v-if="isOpen" class="modal">
                <button @click="toggleModal">Close</button>
    </div>
    </transition>

    </div>
</template>

Named Transitions

Notice how we used the name attribute to give the transition a name of fade. This allows us to prepend our transition’s classes with that name (fade-enter instead of v-enter). Named transitions help us stay organized as our app scales, and makes our transitions more reusable. We may want to use this fade transition on other elements throughout our app, which is why we ought to be naming our transitions based on what they do instead of what element they target. We could’ve named this transition modal but that name just describes this one specific use case, and we may want to fade things that aren’t modals.


Entering Transition

Now we can make use of our named transition classes to create the enter transition, which entails defining the starting style. Remember the questions we should be asking ourselves?

What should the starting style be?

src/views/Home.vue

.fade-enter { /* starting style */
opacity: 0;
}

What should the active entering style be?

src/views/Home.vue

.fade-enter { /* starting style */
opacity: 0;
}

.fade-enter-active { /* entering style */
transition: opacity .5s ease-out;
}

Within .fade-enter-active we defined how we want the CSS transition to behave, specifying what property we’re transitioning (opacity) how long the transition’s duration is (.5s) and the timing function (ease-out).


Leaving Transition

Now that our enter transition is built, we can create our leaving transition.

What should the ending style be?

src/views/Home.vue

.fade-leave-to { /* ending style */
opacity: 0;
}

What should the active leaving style be?

src/views/Home.vue

.fade-leave-active { /* leaving style */
transition: opacity .5s ease-out;
}

As you can see, the transition’s ending style (.fade-leave-to) has opacity at 0 and the leaving state (.fade-leave-active) contains the same CSS transition as our entering transition. Because it’s the same, we can condense our styles like so:

src/views/Home.vue

.fade-enter {
opacity: 0;
}


.fade-enter-active,
.fade-leave-active {
transition: opacity .5s ease-out;
}

.fade-leave-to {
opacity: 0;
}

Additional Transition Classes

If you look at the documentation for Vue’s Enter/Leave transitions, you’ll also find the v-enter-to and v-leave classes. The reason we didn’t cover them in this lesson is because the style we were transitioning to (opacity: 1) was already the default style of our element. The same goes for what we were transitioning away from (opacity: 1). That is why we did not need to explicitly set our opacity to 1 in v-enter-to or v-leave. You’ll only ever need to use these classes when the style you are transitioning to (v-enter-to) or away from (v-leave) is different from the inherent style of the element OR if you run into browser compatibility issues, where these classes may come in handy for you.


Let’s ReVue

In this lesson, we’ve covered what the nature of a transition is, explored the mechanics of Vue’s transition component and its built-in classes, then built our first simple transition, using these questions to guide our decisions:

  • What should the default style be?
  • What should the starting style be?
  • What should the active entering style be?
  • What should the ending style be?
  • What should the active leaving style be?

In the next lesson, we’ll look at using these same concepts to create a page transition using Vue Router.