How to animate components in Vue

Component animations enhance user experience by providing visual feedback for state changes, drawing attention to important elements, and creating polished interfaces. As the creator of CoreUI, a widely used open-source UI library, I’ve implemented smooth animations in Vue applications throughout my 11 years of frontend development. The most versatile approach is using Vue’s built-in Transition component with CSS transitions or animations for declarative animation control. This method provides automatic class management, supports various animation types, and integrates seamlessly with Vue’s reactivity system.

Wrap elements with Transition component and define CSS classes for enter/leave animation states.

<script setup>
import { ref } from 'vue'

const show = ref(true)

const toggleShow = () => {
  show.value = !show.value
}
</script>

<template>
  <div class='demo'>
    <button @click='toggleShow'>
      {{ show ? 'Hide' : 'Show' }} Message
    </button>

    <Transition name='fade'>
      <div v-if='show' class='message'>
        Hello! This message animates in and out.
      </div>
    </Transition>

    <Transition name='slide'>
      <div v-if='show' class='card'>
        <h3>Animated Card</h3>
        <p>This card slides in from the right.</p>
      </div>
    </Transition>

    <Transition name='bounce'>
      <div v-if='show' class='alert'>
        Important notification!
      </div>
    </Transition>
  </div>
</template>

<style>
/* Fade animation */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

/* Slide animation */
.slide-enter-active,
.slide-leave-active {
  transition: all 0.4s ease;
}

.slide-enter-from {
  transform: translateX(100%);
  opacity: 0;
}

.slide-leave-to {
  transform: translateX(-100%);
  opacity: 0;
}

/* Bounce animation */
.bounce-enter-active {
  animation: bounce-in 0.5s;
}

.bounce-leave-active {
  animation: bounce-in 0.5s reverse;
}

@keyframes bounce-in {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.1);
  }
  100% {
    transform: scale(1);
  }
}

/* Component styles */
.demo {
  padding: 2rem;
}

.message,
.card,
.alert {
  margin-top: 1rem;
  padding: 1rem;
  border-radius: 0.5rem;
}

.message {
  background: #e3f2fd;
  color: #1976d2;
}

.card {
  background: #ffffff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.alert {
  background: #fff3cd;
  color: #856404;
  border: 1px solid #ffc107;
}
</style>

Here the Transition component wraps elements that should animate when shown or hidden. The name prop prefixes CSS class names that Vue applies automatically during transitions. Vue adds six transition classes: -enter-from, -enter-active, -enter-to, -leave-from, -leave-active, -leave-to. The fade animation uses CSS transition property for smooth opacity changes. The slide animation combines transform and opacity for directional movement. The bounce animation uses CSS @keyframes for more complex animation sequences. All animations trigger automatically when the v-if condition changes, with no manual class management needed.

Best Practice Note:

This is the animation approach we use in CoreUI Vue components for smooth, performant UI transitions in enterprise applications. Use TransitionGroup for animating lists with move transitions, implement JavaScript hooks (before-enter, enter, after-enter) for programmatic animations when CSS isn’t sufficient, and consider using animation libraries like GSAP with Vue’s JavaScript hooks for complex timeline-based animations in data visualizations or interactive features.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author