LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 3016 min read

Transitions & Animations

Animate elements entering, leaving, and changing using Vue's built-in <Transition> and <TransitionGroup> components.

The <Transition> Component

Wrapping a single element (typically one toggled by v-if or v-show) in <Transition> automatically applies CSS classes as it enters and leaves, which you define the animation for in your own stylesheet.

<template>
<button @click="show = !show">Toggle</button>
<Transition name="fade">
<p v-if="show">Hello there!</p>
</Transition>
</template>

CSS Transition Classes

Vue applies a predictable set of classes, prefixed with the name you gave the <Transition>, at each phase of entering and leaving.

ClassApplied During
fade-enter-fromThe very start of entering (removed on the next frame)
fade-enter-activeThe entire entering phase — define your transition/duration here
fade-enter-toThe end state of entering
fade-leave-fromThe very start of leaving
fade-leave-activeThe entire leaving phase
fade-leave-toThe end state of leaving (usually the "hidden" appearance)

A Fade Transition Example

<style scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
Only Four Classes to Remember

In practice you almost always only need to define the -active (duration/easing) and -from (starting state) classes; -enter-to and -leave-from usually match the element's natural resting state.

Animating Lists with <TransitionGroup>

<TransitionGroup> applies the same enter/leave animation to every item in a v-for list, and additionally animates items moving position (e.g. after a sort or filter) when combined with a move class.

<template>
<TransitionGroup name="list" tag="ul">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</TransitionGroup>
</template>
<style scoped>
.list-enter-active, .list-leave-active { transition: all 0.3s ease; }
.list-enter-from, .list-leave-to { opacity: 0; transform: translateX(20px); }
.list-move { transition: transform 0.3s ease; }
</style>

Common Beginner Mistakes

Wrapping multiple elements directly in one <Transition>

<Transition> expects exactly one root element (or one toggled by v-if/v-else) inside it — for lists, use <TransitionGroup> instead.

Forgetting :key on items inside <TransitionGroup>

Without a stable key, Vue can't correctly track which specific item is entering, leaving, or moving.

FAQs

Yes — <Transition> also supports JavaScript hooks (@before-enter, @enter, @leave) for integrating with animation libraries like GSAP.

Yes, by default a <span>, though the tag prop lets you specify a different element (like "ul" for a list, as shown above).

Summary

<Transition> and <TransitionGroup> give you CSS-class-driven animations for elements and lists, without hand-writing the enter/leave logic yourself. With advanced template features covered, the next section moves into routing and state management for multi-page apps.

Next Lesson →

Vue Router Basics