Tilt Card
3D 透視傾斜卡片:卡片隨游標透視傾斜、眩光跟隨游標滑過表面、離開後 spring 回正,內容可 translateZ 浮起。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
12
1.02
<TiltCard />
安裝
npx shadcn@latest add https://webberui.com/r/tilt-card.json安裝時會一併寫入 --wb-duration-fast CSS 變數到你的全域樣式。
安裝依賴後,複製 tilt-card.tsx 到你的 components/ui/ 目錄,並在全域 CSS 加入:
npm install motion clsx tailwind-merge:root {
--wb-duration-fast: 200ms;
}使用
import { TiltCard, TiltCardItem } from "@/components/ui/tilt-card";
<TiltCard maxTilt={12} scale={1.02}>
<div className="h-40 rounded-t-xl bg-neutral-100 dark:bg-neutral-800" />
<TiltCardItem z={40} className="p-5">
<h3 className="font-semibold">標題</h3>
<p className="text-sm text-neutral-500">這段內容浮在卡面上方 40px。</p>
</TiltCardItem>
</TiltCard>Props
TiltCard
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
maxTilt | number | 12 | 最大傾斜角度(度),游標移至卡片邊緣時 rotateX / rotateY 達到此角度 |
glare | boolean | true | 是否顯示跟隨游標的眩光層 |
scale | number | 1.02 | hover 時卡片放大倍率,1 表示不放大 |
springConfig | SpringOptions | { stiffness: 300, damping: 25, mass: 0.5 } | 傾斜、放大與回正共用的 spring 參數 |
className | string | — | 卡片本體樣式(預設為中性色圓角卡片,可覆蓋;請勿加 overflow-hidden) |
children | ReactNode | — | 卡片內容 |
其餘 <div> 屬性(onClick、aria-* 等)透傳至外層 perspective 容器。
TiltCardItem
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
z | number | 40 | 沿 Z 軸朝觀者浮起的高度(px) |
className | string | — | 自訂樣式 |
children | ReactNode | — | 要浮起的內容 |
細節
- 3D 透視:外層容器固定
perspective: 1000px,卡片本體transform-style: preserve-3d;rotateX / rotateY 依游標相對中心位置線性映射至 ±maxTilt - 眩光:radial-gradient 白色高光跟隨游標位置,強度隨游標離中心的距離增強(正對中心時為 0,越傾斜越亮);可透過
--wb-tilt-glareCSS 變數覆蓋高光顏色(預設rgba(255, 255, 255, 0.4)) - spring 回正:所有變形以
useMotionValue+useSpring驅動,游標離開後帶慣性回正、眩光淡出 - 浮起層次:
TiltCardItem以translateZ讓內容浮出卡面;需為TiltCard的直接子元素,若中間隔了其他容器,請為該容器加上transform-style: preserve-3d - 避免 overflow-hidden:卡片本體若設
overflow-hidden會強制攤平 3D(translateZ失效),滿版圖片請改為在圖片自身加上圓角(如rounded-t-xl) - 穩定不抖動:pointer 事件掛在未變形的外層容器,避免卡片旋轉中讀取到變形後的邊界造成回饋抖動
- 觸控裝置自動停用:僅回應滑鼠的 pointer 事件(
pointerType === "mouse"),觸控時就是一張普通卡片 - 使用者系統開啟「減少動態效果」時停用傾斜與眩光,卡片保持靜態、內容與功能不受影響