Tilt

A card that tilts in 3D toward the pointer.

Black porcelain mug with a square handle and natural clay accents

Dark Grey

Matt Mug

$20

"use client"

import Image from "next/image"
import { Tilt, TiltContent } from "@animate-ui/react/primitives/effects/tilt"

const COLORS = ["bg-neutral-800", "bg-red-950", "bg-blue-950"]

export default function TiltDemo({
  maxTilt = 10,
  perspective = 800,
}: {
  maxTilt?: number
  perspective?: number
}) {
  return (
    <Tilt
      maxTilt={maxTilt}
      perspective={perspective}
      className="w-full max-w-60"
    >
      <TiltContent className="flex flex-col gap-3 rounded-2xl border bg-card p-2 pb-5 shadow-sm">
        <Image
          src="/demos/mug.webp"
          alt="Black porcelain mug with a square handle and natural clay accents"
          width={240}
          height={240}
          className="aspect-square w-full rounded-xl bg-white object-cover"
          draggable={false}
        />
        <div className="text-center">
          <p className="text-xs text-muted-foreground">Dark Grey</p>
          <h3 className="font-medium">Matt Mug</h3>
          <p className="text-sm">$20</p>
        </div>
        <ul className="flex items-center justify-center gap-2">
          {COLORS.map((color) => (
            <li key={color} className={`size-4 rounded-full border ${color}`} />
          ))}
        </ul>
      </TiltContent>
    </Tilt>
  )
}

Installation

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

Usage

import { Tilt, TiltContent } from '@animate-ui/react/primitives/effects/tilt';

export function ProductCard() {
  return (
    <Tilt maxTilt={10}>
      <TiltContent className="rounded-2xl border p-4">
        <img src="/mug.webp" alt="Mug" />
        <h3>Matt Mug</h3>
      </TiltContent>
    </Tilt>
  );
}

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

Animation

  • The content rotates up to maxTilt 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 React.
  • Under reduced motion, the content stays flat.

API Reference

Tilt

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

TiltContent

PropTypeDefault
asChild?
booleanfalse
...props?
HTMLMotionProps<'div'>-

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

Last updated: 10/18/2026

On this page