Masonry Grid
響應式瀑布流佈局並動畫重排,卡片隨欄數與資料變化平滑補位。
以絕對定位排入最矮的欄,形成高低錯落的瀑布流。欄數隨容器寬度改變,資料增刪或順序調換時每張卡都會平滑補位。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
3
16
0.05
<MasonryGrid />
安裝
npx shadcn@latest add https://webberui.com/r/masonry-grid.json或在 components.json 設定 registries 後,改用 @webberui/masonry-grid 安裝。
安裝依賴後,從 registry JSON(/r/masonry-grid.json 的 files[0].content)複製 masonry-grid.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge lucide-react使用
import { MasonryGrid, type MasonryItem } from "@/components/ui/masonry-grid";
const items: MasonryItem[] = [
{ id: "a", height: 200, className: "bg-sky-500" },
{ id: "b", height: 140, className: "bg-rose-500" },
{ id: "c", height: 260, className: "bg-emerald-500" },
];
<MasonryGrid items={items} columns={{ 0: 1, 640: 2, 1024: 3 }} gap={16} />;columns 可以是固定數字(例如 3),也可以是「容器寬度斷點對照表」:鍵是容器最小寬度(px),值是該寬度以上的欄數。斷點依「容器寬度」而非視窗寬度判定,因此放在側欄或彈窗中也能正確排版。
每筆 item 的 height 決定卡片高度,寬度則由欄寬自動計算;把內容放進 content,或用 className 直接套漸層背景。
Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
items | MasonryItem[] | — | 網格項目資料 |
columns | number | Record<number, number> | { 0: 1, 480: 2, 768: 3, 1024: 4 } | 固定欄數或響應式斷點對照表 |
gap | number | 16 | 卡片間距(px) |
duration | number | 0.5 | 單張卡片動畫時長(秒) |
stagger | number | 0.05 | 進場時每張卡的間隔(秒) |
animateFrom | "bottom" | "top" | "left" | "right" | "center" | "bottom" | 進場起始方向 |
blurToFocus | boolean | true | 進場時是否由模糊到清晰 |
scaleOnHover | boolean | true | 懸停時是否輕微放大卡片 |
ease | [number, number, number, number] | [0.22, 1, 0.36, 1] | 動畫緩動曲線 |
MasonryItem
| 欄位 | 型別 | 說明 |
|---|---|---|
id | string | 唯一識別,重排動畫以此追蹤同一張卡 |
height | number | 卡片高度(px),寬度由欄寬自動決定 |
content | React.ReactNode | 卡片內容;未提供時渲染佔位面板 |
className | string | 附加在卡片外框上的樣式 |
可及性
- 使用者系統開啟「減少動態效果」時,卡片直接就位、不播放進場與重排動畫
- 排版於客戶端量測容器寬度後才渲染,避免 SSR 與客戶端不一致(hydration mismatch)
- 以
ResizeObserver監看容器寬度,離開時自動斷開,尺寸變化即時重排