頁面區塊 Sections
瀑布流評價牆
不等高評價卡組成的瀑布流牆,各欄以不同速度隨捲動視差位移,背景有緩慢變形的生成式色塊,可展開更多。
用在首頁或定價頁的客戶評價區塊。卡片依引言字數估計高度,以「最短欄優先」分配到 2–4 欄,長短不一的引言自然排成錯落的瀑布流;捲動經過時第 1、3 欄往上、第 2 欄往下各自視差位移,背景三個大模糊色塊緩慢平移變形。初始只顯示部分卡片,底部有漸層遮罩與「顯示更多評價」按鈕,展開後新卡淡入、遮罩淡出,按鈕改為「收合」。精選卡(featured)會改用強調色底並放大字級。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add masonry-review-wallPlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
1
9
500
編輯中的呼叫預設屬性
<MasonryReviewWall/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/masonry-review-wall.json或在 components.json 設定 registries 後,改用 @webberui/masonry-review-wall 安裝。
使用
import { MasonryReviewWall } from "@/components/ui/masonry-review-wall";
<MasonryReviewWall
eyebrow="客戶評價"
title="客戶怎麼說"
columns={3}
initialCount={9}
testimonials={[
{
quote: "導入三週,門市備料浪費少了一大截。",
name: "林語晴",
role: "營運主管",
company: "青嶼咖啡",
rating: 5,
highlight: "備料浪費少了一大截",
featured: true,
},
{
quote: "排班表終於不用每週手動調三輪。",
name: "王思妤",
role: "調度經理",
company: "北辰物流",
metric: { value: "−62%", label: "手動調班時數" },
},
]}
/>放在巢狀捲動容器內
預設追蹤的是視窗的捲動。若元件放在固定高度的 overflow-y-auto 容器內,請把該容器的 ref 傳給 container。各欄的視差位移跟著評價牆在容器內的捲動進度走;收合時的捲回也以該容器的可視範圍判斷。
const scrollerRef = React.useRef<HTMLDivElement>(null);
<div ref={scrollerRef} className="h-[400px] overflow-y-auto">
<MasonryReviewWall container={scrollerRef} />
</div>以整個視窗為捲動容器時可省略 container,行為與原本相同。
Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
testimonials | MasonryReviewWallItem[] | — | 評價資料,依序以最短欄優先分配到各欄 |
eyebrow | string | "客戶評價" | 標題上方的小標 |
title | string | "客戶怎麼說" | 區塊標題;同時作為 section 的無障礙名稱 |
subtitle | string | — | 標題下方的說明文字 |
columns | 2 | 3 | 4 | 3 | 寬螢幕欄數;容器窄於 880px 最多 2 欄、窄於 560px 為 1 欄 |
initialCount | number | 9 | 收合時顯示的卡片數;資料數不超過此值時不顯示按鈕 |
parallax | number | 1 | 捲動視差強度倍率;0 關閉,1 為各欄位移 40px |
showRating | boolean | true | 資料有 rating 時是否顯示星等 |
expanded | boolean | — | 受控的展開狀態;未提供時由元件內部管理 |
defaultExpanded | boolean | false | 非受控模式的初始展開狀態 |
onExpandedChange | (expanded: boolean) => void | — | 展開狀態變動時回呼 |
moreLabel | string | "顯示更多評價" | 展開按鈕文字 |
lessLabel | string | "收合" | 全部顯示後的收合按鈕文字 |
container | RefObject<HTMLElement> | — | 巢狀捲動容器的 ref;省略則以視窗為捲動容器 |
className | string | — | 附加到根 section |
MasonryReviewWallItem
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
quote | string | — | 評價內文 |
name | string | — | 評價者姓名;頭像縮寫取中文末兩字或拉丁字首 |
role | string | — | 職稱 |
company | string | — | 公司或單位,與職稱以「·」連接 |
rating | number | — | 星等 1–5 |
avatarHue | number | — | 頭像漸層色相;未提供時依索引以黃金角度分配 |
highlight | string | — | quote 中要以強調色標記的片段 |
metric | { value: string; label: string } | — | 卡片底部的成效數字 |
featured | boolean | false | 精選卡:強調色 8% 底色、字級放大 |
細節
- 分欄是確定性的:以引言字數估計卡片高度,依序放進目前最矮的欄,伺服器與瀏覽器算出同一個結果;展開時新卡只會接在各欄底部,已顯示的卡片不會換欄。
- 欄數在掛載後依容器寬度調整(ResizeObserver),所以放在窄側欄或手機上也會自動降為 1 欄。
- 節奏可用 CSS 變數覆寫:
--wb-masonry-review-wall-duration(卡片進場,預設 500ms,欄內每張依序延遲 60ms)、--wb-masonry-review-wall-backdrop(背景色塊變形週期,預設 24s)、--wb-masonry-review-wall-hover(hover 上浮與陰影,預設 150ms)。 - 強調色走
--wb-masonry-review-wall-accent(預設亮色#0d9488、暗色#2dd4bf),影響小標、精選卡底色、標記片段、成效數字與背景色塊。 - 底部漸層用 CSS
mask-image讓卡片本身淡出,而不是疊一層底色,放在任何背景上都成立;背景色塊離開視口時暫停動畫。
可及性
- 根元素是
<section aria-labelledby>,指向標題h2;沒有標題時改用aria-label - 每則評價以
figure/blockquote/figcaption呈現,星等是帶aria-label的role="img",頭像縮寫對輔助科技隱藏 - 展開按鈕帶
aria-expanded與aria-controls,展開或收合後由aria-live區域朗讀目前顯示的則數;收合時若按鈕已捲出視窗會自動捲回 - 使用者系統開啟「減少動態效果」時,停用捲動視差、背景色塊變形與 hover 上浮,卡片進場改為 150ms 淡入,展開/收合仍可正常使用