Variants

Variants represent an animatable state for your element.

They are composed of any Motion Properties and an optional Transition Properties.

<div
  v-motion
  :initial="{
    opacity: 0,
    y: 100,
  }"
  :enter="{
    opacity: 1,
    y: 0,
    transition: {
      type: 'spring',
      stiffness: '100',
      delay: 100,
    },
  }"
/>
This element will fade in smoothly after 100ms. ☝️

Initial Variant

The initial variant represents the base state of the focused element.

It combines with :style, and is applied at the creation of the element.

It is recommended to include a base state for each parameter that you are willing to animate using subsequent variants.

<div
  v-motion
  :initial="{
    opacity: 0,
    y: 100,
  }"
/>
This element will be hidden, and 100px above of its original position. ☝️

Lifecycle Variants

Enter

The enter variant will be applied on the second tick of the element, right after its creation.

You can use it to trigger an animation when the element appears, transitioning from Initial variant.

<div
  v-motion
  :initial="{
    opacity: 0,
    y: 100,
  }"
  :enter="{
    opacity: 1,
    y: 0,
  }"
/>
This element will fade in smoothly on page mount. ☝️

Leave

The leave variant helps to define the state of an element when it is supposed to leave the DOM.

<div
  v-motion
  :initial="{
    opacity: 0,
    y: 100,
  }"
  :enter="{
    opacity: 1,
    y: 0,
  }"
  :leave="{
    y: -100,
    opacity: 0,
  }"
/>

In order to achieve a leave transition, you will have to access the Motion Instance.

This instance exposes an helper called leave than can easily be mapped with the Vue transition element @leave event.

You can take a look at an example of implementation on the Demo page, at the "Transitions" section.

Visibility Variants

Visible

The visible variant will be applied when the element enters the viewport.

When the element leaves, the Initial variant will be applied again.

<div
  v-motion
  :initial="{
    opacity: 0,
    y: 100,
  }"
  :visible="{
    opacity: 1,
    y: 0,
  }"
/>
This element will fade in smoothly each times it enters the viewport. ☝️

Events Variants

Variants can also be used to interact with the element using event listeners.

These event listeners are only registered if you specify those variants.

Note that these variants won't be replacing the current variant of the element, but only alter it while the event are active.

A meta-variant will be generated by combining all the active ones, using the following order:

  • Hovered (lowest priority)
  • Focused
  • Tapped (highest priority)

Doing this allows a smoother transition between each of these states and allows you to interact with elements while they're being animated.

Hovered

A regular hover event listener, it will not work on mobile devices.

<div
  v-motion
  :initial="{
    scale: 1,
  }"
  :hovered="{
    scale: 1.2,
  }"
/>
This element will scale up on hover. ☝️

Focused

A regular focus event listener.

<div
  v-motion
  :initial="{
    scale: 1,
  }"
  :focused="{
    scale: 1.1,
  }"
/>
This element will scale up on focus. ☝️

Tapped

An event listener combining mouse and touch events seamlessly.

It will switch between them depending on the user supported pointer events.

<div
  v-motion
  :initial="{
    scale: 1,
  }"
  :tapped="{
    scale: 0.8,
  }"
/>
This element will scale down on tap. ☝️

Custom variants

You can create your own variants and apply them using the motion instance.

<template>
  <div v-motion="'customElement'" :initial="{ scale: 1, }" :variants="{ custom:
  { scale: 2, transition: { type: "spring", stiffness: 100 } } }" />
</template>

<script setup>
import { useMotions } from '@vueuse/motion'

// Access the motion instance using useMotions.
const { customElement } = useMotions()

// Dummy custom event function
const yourCustomEvent = () => {
  // Edit the variant using the motion instance.
  customElement.variant.value = 'custom'
}
</script>
A nice custom variant example. ☝️