Tilt

A card that tilts in 3D toward the pointer.

<script setup lang="ts">
import { Tilt, TiltContent } from '@animate-ui/vue/primitives/effects/tilt'

withDefaults(
  defineProps<{ maxTilt?: number | string, perspective?: number | string }>(),
  { maxTilt: 10, perspective: 800 },
)

const COLORS = ['bg-neutral-800', 'bg-red-950', 'bg-blue-950']
</script>

<template>
  <Tilt :max-tilt="Number(maxTilt)" :perspective="Number(perspective)" class="w-full max-w-60">
    <TiltContent class="flex flex-col gap-3 rounded-2xl border bg-card p-2 pb-5 shadow-sm">
      <img
        :src="'/demos/mug.webp'"
        alt="Black porcelain mug with a square handle and natural clay accents"
        width="240"
        height="240"
        class="aspect-square w-full rounded-xl bg-white object-cover"
        draggable="false"
      >
      <div class="text-center">
        <p class="text-xs text-muted-foreground">
          Dark Grey
        </p>
        <h3 class="font-medium">
          Matt Mug
        </h3>
        <p class="text-sm">
          $20
        </p>
      </div>
      <ul class="flex items-center justify-center gap-2">
        <li v-for="color in COLORS" :key="color" :class="`size-4 rounded-full border ${color}`" />
      </ul>
    </TiltContent>
  </Tilt>
</template>

Installation

npm install @animate-ui/vue motion-v
pnpm add @animate-ui/vue motion-v
yarn add @animate-ui/vue motion-v
bun add @animate-ui/vue motion-v

Usage

<script setup lang="ts">
import { Tilt, TiltContent } from '@animate-ui/vue/primitives/effects/tilt';
</script>

<template>
  <Tilt :max-tilt="10">
    <TiltContent class="rounded-2xl border p-4">
      <img src="/mug.webp" alt="Mug" />
      <h3>Matt Mug</h3>
    </TiltContent>
  </Tilt>
</template>

Tilt tracks the pointer and sets the perspective; TiltContent is the part that rotates.

Animation

  • The content rotates up to max-tilt degrees toward the pointer on a spring, and flattens back when it leaves.
  • The rotation is driven by motion values: moving the pointer never re-renders Vue.
  • Under reduced motion, the content stays flat.

API Reference

Tilt

PropTypeDefault
as-child?
booleanfalse
max-tilt?
number10
perspective?
number800
transition?
SpringOptions{ stiffness: 300, damping: 25, mass: 0.5 }
...props?
HTMLMotionProps<'div'>-

TiltContent

PropTypeDefault
as-child?
booleanfalse
...props?
HTMLMotionProps<'div'>-

Built by Skyleen. The source code is available on GitHub.

Last updated: 10/23/2026