Introduction
Animations and transitions are a great way to enhance user experiences in web apps. Vue provides easy APIs for applying transition effects when items are inserted, updated, or removed from the DOM.
In this comprehensive guide, you’ll learn:
- What are transitions in Vue and how they work
- Using transition components for enter/leave animations
- CSS transition classes for durations, delays, and easing
- Animating list reorderings with transition groups
- Using 3rd party CSS animation libraries like Animate.css
- Transitioning between multiple states with keyframes
- Reusable transition components and hooks
- Common transition patterns for modal dialogs and page routes
- Examples to inspire creative transition effects
By the end, you’ll feel empowered to liven up your Vue apps with smooth, subtle, and fun animation transitions.
What are Transitions in Vue.js?
Vue provides transition system that allows animating the insertion and deletion of elements in your app. This includes:
- Applying classes for CSS transitions and animations
- Automatically detecting when elements are inserted/removed
- Coordinating animations across components
With transitions, you can animate the following cases:
- Conditionally rendered elements using v-if
- Toggle showing elements with v-show
- Dynamic component changes with <component>
- List reorderings when using v-for
The key is Vue’s transition components add/remove classes at appropriate timing points to trigger CSS transitions you define.
Some benefits of using transitions:
- Animate user-facing state changes in the app
- Improved perceived performance from animation
- Add visual flourish to engage users
Let’s dive in and see transitions in action!
Transition Components Basics
Vue includes two transition wrapper components:
<transition>
for single element/component transitions<transition-group>
for multiple element transitions
These allow declaring:
- JavaScript hooks for transition stages
- CSS classes to define transition durations and styles
Let’s look at them both more closely:
Single Element Transitions with <transition>
<transition>
wraps a single element or component to animate transitioning in and out of the DOM:
<transition>
<p v-if="show">hello</p>
</transition>
It applies classes for us to use in CSS:
v-enter-from
– Starting state for enterv-enter-active
– Active state for enterv-enter-to
– Ending state for enterv-leave-from
– Starting state for leavev-leave-active
– Active state for leavev-leave-to
– Ending state for leave
For example, a fade transition:
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
The transition component detects adding/removing the inner element and applies these classes to trigger CSS transitions you define.
Transitioning Between Elements
<transition>
can also transition between different elements/components using mode="out-in"
or mode="in-out"
:
<transition mode="out-in">
<ChildComponent v-if="state === 'A'"></ChildComponent>
<OtherComponent v-else></OtherComponent>
</transition>
The new element animates in first before the previous element animates out.
JavaScript Transition Hooks
<transition>
allows hooking into the transition lifecycle with JavaScript:
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@enter-cancelled="enterCancelled"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave"
@leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
This enables coordinating animations, delays, microtasks and other logic around transition stages.
Transition Group Basics
For transitioning a list of elements like v-for, <transition-group>
is used instead.
<transition-group>
renders a real element to wrap the list making reordering easier:
<transition-group tag="ul">
<li v-for="item in items" :key="item">
{{ item }}
</li>
</transition-group>
Now when items change order, it applies transition classes so they animate to new positions smoothly.
In addition to the classes above, it provides:
v-move
– Applied during moving transitions
Let’s look deeper at animating lists.
Animating List Reordering
A great benefit of <transition-group>
is animating reordering of lists.
For example, given this list rendering:
<transition-group name="fade" tag="ul">
<li v-for="item in items" :key="item">
{{ item }}
</li>
</transition-group>
We can animate reordering like so:
.fade-move {
transition: transform 0.5s ease;
}
Whenever an item changes position, it applies a moving transition!
Some key points:
- Use
:key
binding to animate moving elements vs add/remove - List position determined by
:key
ordering - Use
transform: translate
for hardware acceleration
This brings static lists to life with smooth reordering animations!
CSS Transition Classes
The v-enter/leave
transition classes apply some common properties:
- Timeouts – delays before transition starts
- Durations – transition durations applied
- Timing functions – easing curves like
ease-in-out
For example, a 1 second fade transition with a 0.3s delay before entering:
.fade-enter-active {
transition: opacity 1s;
transition-delay: 0.3s;
opacity: 0;
}
Customizing these timings and easing curves unlocks more advanced transitions.
Using 3rd Party CSS Animation Libraries
For convenience, JavaScript animation libraries like Animate.css can be dropped in:
<link href="animate.css" rel="stylesheet" />
<transition
enter-active-class="animate__animated animate__bounce"
leave-active-class="animate__animated animate__bounceOutRight"
>
<!-- ... -->
</transition>
This allows using pre-made animation effects easily.
Keyframes Transitions
For multi-state transitions, keyframes can be used.
First define keyframe animations in CSS:
@keyframes slideDown {
0% { transform: translateY(-100%); }
100% { transform: translateY(0); }
}
Then reference them from transition classes:
<transition
enter-active-class="slideDown"
leave-active-class="slideUp"
/>
This enables sequencing more complex transitions.
Reusable Transitions with Components
Repeated transitions can be extracted out to reusable components:
// FadeTransition.vue
export default {
props: {
// ...
}
beforeEnter(el) {
// ...
},
methods: {
onBeforeEnter() {
// ...
}
}
}
Then use via:
<FadeTransition>
<p v-if="show">hello</p>
</FadeTransition>
This encapsulates the transition logic in a reusable way.
Common Transition Patterns
Some common patterns using transitions:
Page Transitions
Animate route changes:
const router = new VueRouter({
mode: 'history',
routes: [
// ...
]
})
const app = createApp(/* */)
app.use(router)
app.component('page-transition', {
beforeEnter(el) {
// coordinate transitions
}
})
Modal Dialogs
Fade in overlays:
<teleport to="body">
<transition name="modal-fade">
<div class="modal-overlay" v-if="showModal">
<div class="modal">
<!-- content -->
</div>
</div>
</transition>
</teleport>
These patterns provide visual continuity when changing app state.
Creative Examples and Inspiration
Some examples showing creative ways to use transitions:
- Animate emojis for user reactions
- Add flare to image galleries as slides change
- Use animated SVGs as loading indicators
- Animate cards flying in when added to lists
- Show waterfall charts growing or shrinking
- Animate likes filling up an empty heart icon
- Expand cards on hover with a bounce effect
- Animate todo items checked off the list
The possibilities are endless for crafting fun, engaging transitions in your app!
Common Transition Gotchas
Here are some common pitfalls and how to avoid them:
- Forgetting the
:key
attribute on list items will prevent proper transition classes being applied on reorder. - Transitions on root nodes need to be applied on the component or an inner wrapper element.
- Use
appear
attribute to apply on initial render and not just subsequent transitions. - Avoid animating height unless there is an intrinsic height set.
- JavaScript hooks should be used only for coordination, do the actual animation in CSS.
- Be wary of transitions causing unwanted side effects on other elements.
Frequently Asked Questions
Do transitions work with Vue router?
Yes! Router view transitions are a great way to animate page navigation.
Is CSS animation better than JavaScript animation?
In most cases, yes – do the heavy animation lifting in CSS and use JS only to coordinate.
Can I use libraries like GSAP?
Absolutely. Hooks enable integrating libraries like GSAP, Velocity etc.
How can transitions be reused between components?
Extract the transition to a reusable component or custom hook.
What is FLIP animations in transitions?
Using transforms to animate the existing element from old to new position on reorder.
Conclusion
Transitions are an easy way to elevate your Vue apps with thoughtful motion design. By applying them creatively to UI state changes, lists, page navigation, and more – you can delight users and keep them engaged.
Leveraging Vue’s transition components hooks and timeline events, it’s simple to animate your app’s dynamic changes. Do creative exploration with CSS transitions, keyframes, and libraries like Animate.css.
Animations breathe life into apps when done right. Learn the core transition techniques, and you’ll be ready to animate awesome interfaces in Vue. Just don’t overdo it – subtle and meaningful animation goes a long way.
With Vue handling the complexity behind the scenes, you’re free to focus on innovating fun transitions that make your users smile.