WebberUI

Hero Condense Header

捲動時英雄區的標題、頭像與 meta 以共享元素 FLIP 逐一遷移收攏進吸頂頁首,向上捲回再依序展開歸位。

載入預覽⋯

Playground

即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。

240
56
0.5
<HeroCondenseHeader />

安裝

npx shadcn@latest add https://webberui.com/r/hero-condense-header.json

安裝依賴後,從 registry JSON(/r/hero-condense-header.jsonfiles[0].content)複製 hero-condense-header.tsx 原始碼到你的 components/ui/ 目錄:

npm install motion clsx tailwind-merge

使用

items 陣列裡的每個項目都是「同一個」在英雄區與吸頂列之間遷移的共享節點。heroClassName 定位它在英雄區的錨點(決定展開時的位置與尺寸),headerClassName 決定它收攏後在吸頂列的排版:

import {
  HeroCondenseHeader,
  type HeroCondenseItem,
} from "@/components/ui/hero-condense-header";

const items: HeroCondenseItem[] = [
  {
    id: "avatar",
    content: <img src="/me.jpg" alt="Aria" className="h-full w-full rounded-full" />,
    heroClassName: "inset-x-0 mx-auto top-9 h-16 w-16",
    headerClassName: "order-1 h-8 w-8 shrink-0",
  },
  {
    id: "title",
    content: <span className="whitespace-nowrap text-sm font-semibold">Aria Nakamura</span>,
    heroClassName: "inset-x-0 mx-auto top-[104px] h-7 w-56",
    headerClassName: "order-2",
  },
  {
    id: "meta",
    content: <span className="whitespace-nowrap text-xs text-neutral-500">Product Designer</span>,
    heroClassName: "inset-x-0 mx-auto top-[136px] h-5 w-64",
    headerClassName: "order-3 ml-auto",
  },
];

<HeroCondenseHeader items={items} heroHeight={240} headerHeight={56}>
  <YourPageContent />
</HeroCondenseHeader>

捲動容器可以是頁面本身(預設以視窗為捲動容器),也可以是任何 overflow-y: auto 的區塊——後者把該容器的 ref 傳入 container 即可(如上方示範)。

陣列順序即收攏先後:第一個項目最先收攏、最後展開;視覺上的列內排列則以 order-* 工具類獨立控制。

Props

Prop型別預設值說明
itemsHeroCondenseItem[]依序遷移的共享元素;陣列順序即收攏先後
heroHeightnumber240英雄區總高度(px)
headerHeightnumber56吸頂頁首列高度(px)
condenseSpannumber0.5單一項目收攏所佔的進度比例(0.05–1),越小交錯越明顯
containerReact.RefObject<HTMLElement | null>捲動容器 ref;巢狀 overflow 容器需傳入,預設為視窗
heroClassNamestring英雄層樣式(背景、圓角等)
barClassNamestring吸頂列容器樣式
childrenReact.ReactNode頁首下方的頁面內容
classNamestring附加到最外層容器的 class

HeroCondenseItem

欄位型別說明
idstring唯一識別碼,用於配對英雄錨點與吸頂插槽
contentReact.ReactNode共享元素內容(同一節點在兩端之間遷移)
heroClassNamestring英雄錨點定位(絕對定位);高度決定展開倍率、中心決定落點
headerClassNamestring吸頂插槽排版;可用 order-* 調整列內順序

細節

  • 展開倍率=錨點高度 / 插槽高度,共享節點以其收攏(吸頂列)尺寸為基準,透過 transform 縮放至英雄尺寸——因此文字顏色不會隨遷移改變,請為英雄層挑選與吸頂列相容的底色
  • 兩端幾何以 offsetParent 鏈量測(transform 前的版面座標),不受捲動與 sticky 位移影響;定位錨點時請用 left/top/inset/mx-auto 等版面屬性,避免 transform 類工具(如 -translate-x-1/2)以免量測失準
  • 遷移全程只用 transform 驅動、不觸發版面重排,並在尺寸或視窗變動時以 ResizeObserver 重新量測
  • 每個項目沿自己的進度視窗(condenseSpan 寬、彼此以 stagger 錯開)補間,因此收攏/展開會逐一發生;condenseSpan 越小、交錯越明顯

可及性

  • 共享文字(姓名、職稱)只渲染一次且始終在 DOM 中,輔助科技可正常朗讀;英雄層的定位錨點為空且標記 aria-hidden
  • 使用者系統開啟「減少動態效果」時,直接渲染靜態的吸頂頁首(收攏態),不播放遷移動畫、也不渲染英雄區,仍是一個可用的頁首
  • 吸頂列使用語意化的 <header> 元素,形成頁面的 banner 地標

On this page