頁面區塊 Sections

瀑布流評價牆

不等高評價卡組成的瀑布流牆,各欄以不同速度隨捲動視差位移,背景有緩慢變形的生成式色塊,可展開更多。

用在首頁或定價頁的客戶評價區塊。卡片依引言字數估計高度,以「最短欄優先」分配到 2–4 欄,長短不一的引言自然排成錯落的瀑布流;捲動經過時第 1、3 欄往上、第 2 欄往下各自視差位移,背景三個大模糊色塊緩慢平移變形。初始只顯示部分卡片,底部有漸層遮罩與「顯示更多評價」按鈕,展開後新卡淡入、遮罩淡出,按鈕改為「收合」。精選卡(featured)會改用強調色底並放大字級。

把這個效果裝進你的專案

在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。

npx webberui@latest add masonry-review-wall

還沒有專案,或安裝遇到問題?看快速開始 →

Playground

即時調整 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型別預設值說明
testimonialsMasonryReviewWallItem[]—評價資料,依序以最短欄優先分配到各欄
eyebrowstring"客戶評價"標題上方的小標
titlestring"客戶怎麼說"區塊標題;同時作為 section 的無障礙名稱
subtitlestring—標題下方的說明文字
columns2 | 3 | 43寬螢幕欄數;容器窄於 880px 最多 2 欄、窄於 560px 為 1 欄
initialCountnumber9收合時顯示的卡片數;資料數不超過此值時不顯示按鈕
parallaxnumber1捲動視差強度倍率;0 關閉,1 為各欄位移 40px
showRatingbooleantrue資料有 rating 時是否顯示星等
expandedboolean—受控的展開狀態;未提供時由元件內部管理
defaultExpandedbooleanfalse非受控模式的初始展開狀態
onExpandedChange(expanded: boolean) => void—展開狀態變動時回呼
moreLabelstring"顯示更多評價"展開按鈕文字
lessLabelstring"收合"全部顯示後的收合按鈕文字
containerRefObject<HTMLElement>—巢狀捲動容器的 ref;省略則以視窗為捲動容器
classNamestring—附加到根 section

MasonryReviewWallItem

欄位型別預設值說明
quotestring—評價內文
namestring—評價者姓名;頭像縮寫取中文末兩字或拉丁字首
rolestring—職稱
companystring—公司或單位,與職稱以「·」連接
ratingnumber—星等 1–5
avatarHuenumber—頭像漸層色相;未提供時依索引以黃金角度分配
highlightstring—quote 中要以強調色標記的片段
metric{ value: string; label: string }—卡片底部的成效數字
featuredbooleanfalse精選卡:強調色 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 淡入,展開/收合仍可正常使用