Common Animation Patterns

+15 Mana ✨

Here are ready-to-use animation patterns for common UI needs.

Fade

vue
<Transition name="fade">
  <div v-if="show">Content</div>
</Transition>

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

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

Slide

vue
<!-- Slide from left -->
<Transition name="slide-left">
  <div v-if="show">Content</div>
</Transition>

<style>
.slide-left-enter-active,
.slide-left-leave-active {
  transition: transform 0.3s ease;
}

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

.slide-left-leave-to {
  transform: translateX(100%);
}
</style>

Scale

vue
<Transition name="scale">
  <div v-if="show">Content</div>
</Transition>

<style>
.scale-enter-active,
.scale-leave-active {
  transition: transform 0.2s ease, opacity 0.2s ease;
}

.scale-enter-from,
.scale-leave-to {
  transform: scale(0.9);
  opacity: 0;
}
</style>

Slide + Fade (Dropdown)

vue
<Transition name="dropdown">
  <ul v-if="isOpen" class="menu">
    <li>Item 1</li>
    <li>Item 2</li>
  </ul>
</Transition>

<style>
.dropdown-enter-active,
.dropdown-leave-active {
  transition: opacity 0.2s ease, transform 0.2s ease;
  transform-origin: top;
}

.dropdown-enter-from,
.dropdown-leave-to {
  opacity: 0;
  transform: scaleY(0.9) translateY(-10px);
}
</style>

Modal/Dialog

vue
<Transition name="modal">
  <div v-if="showModal" class="modal-overlay" @click.self="close">
    <div class="modal-content">
      <slot />
    </div>
  </div>
</Transition>

<style>
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal-enter-active,
.modal-leave-active {
  transition: opacity 0.3s ease;
}

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

.modal-enter-active .modal-content,
.modal-leave-active .modal-content {
  transition: transform 0.3s ease;
}

.modal-enter-from .modal-content,
.modal-leave-to .modal-content {
  transform: scale(0.9) translateY(20px);
}
</style>

Toast Notification

vue
<Transition name="toast">
  <div v-if="showToast" class="toast">
    {{ message }}
  </div>
</Transition>

<style>
.toast {
  position: fixed;
  bottom: 20px;
  right: 20px;
  padding: 12px 24px;
  background: #333;
  color: white;
  border-radius: 8px;
}

.toast-enter-active,
.toast-leave-active {
  transition: all 0.3s ease;
}

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

.toast-leave-to {
  opacity: 0;
  transform: translateY(20px);
}
</style>

Page Transitions

vue
<router-view v-slot="{ Component, route }">
  <Transition name="page" mode="out-in">
    <component :is="Component" :key="route.path" />
  </Transition>
</router-view>

<style>
.page-enter-active,
.page-leave-active {
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.page-enter-from {
  opacity: 0;
  transform: translateY(20px);
}

.page-leave-to {
  opacity: 0;
  transform: translateY(-20px);
}
</style>

Reusable Transition Component

vue
<!-- FadeTransition.vue -->
<script setup>
defineProps<{
  duration?: number
}>()
</script>

<template>
  <Transition name="fade" :style="{ '--duration': duration + 'ms' }">
    <slot />
  </Transition>
</template>

<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity var(--duration, 300ms) ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

<!-- Usage -->
<FadeTransition :duration="500">
  <div v-if="show">Content</div>
</FadeTransition>
✓ Completed