Transitions and Animations

By Syncfusion®, Inc. · Last updated

The <Transition> component and its six CSS classes, named transitions, transition modes, CSS animations, custom class names, JavaScript hooks and :css="false", transitions between components, reusable transitions, <TransitionGroup> with keys, tag and move classes, state-driven animation and reduced motion.

Movement Helps People Follow

  • When something appears or disappears suddenly, people can miss it.
  • A short fade or slide shows what changed and where.
  • Vue's <Transition> adds CSS classes at the right moments when an element enters or leaves.
  • You write the CSS. Vue decides when each class is on.

Simple lesson: <Transition> adds classes while an element enters or leaves. Your CSS animates them.

A Real-World Example

  • Meera's site shows a "Added to cart" message after each order.
  • It should fade in, then fade out, not just pop.
  • What happened: the message faded in, waited, then faded out.
  • name="fade" made Vue use classes that start with fade-.

What You Will Learn

  1. The six transition classes and when they apply.
  2. Named transitions.
  3. Transition modes for switching elements.
  4. CSS keyframe animations.
  5. Custom class names, for CSS libraries.
  6. JavaScript hooks.
  7. Transitions between components, and reusable transitions.
  8. Animating lists with <TransitionGroup>.
  9. Animating numbers from state, and respecting reduced motion.

The Six Classes

  • <Transition> works on one element or component that is added or removed by v-if, v-show, :is or a key change.
  • Entering:

    • v-enter-from: the start. Added before the element appears, removed one frame later.
    • v-enter-active: the whole enter phase. Put the transition here.
    • v-enter-to: the end state.
  • Leaving: v-leave-from, v-leave-active, v-leave-to.
  • With name="fade", v- becomes fade-.
  • Around a component, that component must have one root element, or nothing animates.
  • Add appear to animate the first show when the page loads, too.

Animation: a box fades in from opacity 0 while the classes fade-enter-from, fade-enter-active and fade-enter-to light up on a timeline, then fades out while the leave classes light up

toast

enter-from enter-active (transition here) enter-to leave-from leave-active leave-to

Enter: from → to while active. Leave: from → to while active. Then Vue removes the element.

Vue switches the classes. The transition on the active class does the moving.

Slide and Fade Together

Simple lesson: put transition on -active, and the hidden look on -enter-from and -leave-to.

<Transition> only animates. It does not add or remove anything by itself. The v-if, v-show or :key inside it decides that.

Switching Elements and Modes

  • <Transition> can switch between elements with v-if / v-else, or by changing a key.
  • By default, the old one leaves while the new one enters, at the same time.
  • mode="out-in": the old one leaves first, then the new one enters. Usually the nicest.
  • mode="in-out": the new one enters first. Rarely used.
  • What happened: changing the key made Vue treat it as a new element, so it animated.

CSS Animations and Custom Classes

  • You can use @keyframes animations instead of transitions. Put animation on the -active class.
  • Custom class props replace the default names: enter-active-class, leave-active-class and the rest.
  • This is how you use a CSS animation library, such as Animate.css, with Vue.

Simple lesson: mode="out-in" for clean swaps. Custom classes connect CSS libraries.

JavaScript Hooks

  • <Transition> emits events at each step: @before-enter, @enter, @after-enter, @enter-cancelled, and the same for leave.
  • @enter(el, done) and @leave(el, done) must call done() when the animation finishes.
  • Add :css="false" to tell Vue not to look for CSS classes. It is faster for pure JavaScript animation.
  • Here the browser's Web Animations API (el.animate) does the work.

With :css="false", you must call done() in @enter and @leave. If you forget, Vue never finishes the transition, and a leaving element is never removed.

Components and Reusable Transitions

  • <Transition> works around a component, or around <component :is> and <RouterView>'s slot.
  • To reuse one transition everywhere, wrap it in your own component and pass the content through a slot.

Simple lesson: JavaScript hooks for full control. A small wrapper component makes a transition reusable.

TransitionGroup

  • <TransitionGroup> animates items in a v-for list as they are added, removed or moved.
  • Every item needs a unique key.
  • tag="ul" makes the group render a real <ul> around the items.
  • The extra -move class animates items sliding to their new place.
  • Give leaving items position: absolute, so the others can slide smoothly.

State-Driven Animation

  • Some animations follow a number, not an element entering or leaving.
  • Bind it to a style and add a CSS transition. The browser animates the change.
  • Or move a number smoothly yourself with requestAnimationFrame in a watcher.

Some people feel sick from motion. Respect their system setting with CSS: @media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }. Keep transitions short, around 150 to 400 ms.

Simple lesson: <TransitionGroup> animates lists. For numbers, animate the style or the value.

TL;DR

  • <Transition> = animates one element entering or leaving.
  • Six classes = v-enter-from/active/to, v-leave-from/active/to.
  • name="fade" = class names start with fade-.
  • mode="out-in" = the old element leaves before the new one enters.
  • Custom classes = enter-active-class and friends, for CSS libraries.
  • JavaScript hooks = @enter(el, done), @leave(el, done), :css="false".
  • <TransitionGroup> = animates v-for lists. Needs keys. tag, -move.
  • State-driven = bind styles with a CSS transition, or tween the number.
  • Reduced motion = turn animations off for prefers-reduced-motion.

Common mistakes

MistakeWrong ideaCorrect ideaWhat goes wrong
Two elements in one <Transition>It animates bothOne root only. Use v-if/v-else or :keyA warning, no animation
transition on -enter-fromAny class worksPut transition on -activeThe element jumps without animating
No key when content changesVue sees the changeAdd :key so Vue sees a new elementNo animation on text change
Forgetting done()Vue knows when JS endsCall done() in @enter/@leaveLeaving elements stay forever
No position: absolute on leaving list itemsLists slide by themselvesAdd it to -leave-activeItems jump instead of sliding
Long, flashy animationsMore motion is better150 to 400 ms, respect reduced motionSlow, tiring, or sickening pages

Check Yourself

Exercises

What to Remember

  • <Transition> adds enter and leave classes. Your CSS does the animation.
  • Put transition on -active, the hidden look on -enter-from and -leave-to.
  • Use mode="out-in" and :key for clean swaps.
  • JavaScript hooks must call done(). <TransitionGroup> animates keyed lists.
  • Keep motion short, and respect reduced motion.

Next: Render Functions and Component Patterns