Parallax Section
多層視差區塊,每層依滾動進度以不同速度位移,堆疊出景深與空間感。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
120
0.5
<ParallaxSection />
安裝
npx shadcn@latest add https://webberui.com/r/parallax-section.json或在 components.json 設定 registries 後,改用 @webberui/parallax-section 安裝。
安裝依賴後,從 registry JSON(/r/parallax-section.json 的 files[0].content)複製 parallax-section.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge使用
以 ParallaxSection 作為容器,內部放入多個 ParallaxLayer。多數視差層以 absolute inset-0 疊放,並用 speed 決定每層相對捲動的位移倍率:
import {
ParallaxLayer,
ParallaxSection,
} from "@/components/ui/parallax-section";
<ParallaxSection className="h-[420px] bg-neutral-950">
{/* 後景:慢速下沉 */}
<ParallaxLayer decorative speed={-0.6} className="absolute inset-0">
<div className="absolute inset-0 bg-gradient-to-b from-indigo-500/30 to-transparent" />
</ParallaxLayer>
{/* 前景:快速上浮並淡出 */}
<ParallaxLayer
speed={1.2}
fade
className="absolute inset-0 flex items-center justify-center"
>
<h2 className="text-4xl font-bold text-white">多層視差</h2>
</ParallaxLayer>
</ParallaxSection>;巢狀捲動容器
若視差發生在固定高度、內部捲動的容器中(而非整個視窗),把該容器的 ref 傳給 container:
const scrollerRef = React.useRef<HTMLDivElement>(null);
<div ref={scrollerRef} className="h-[300px] overflow-y-auto">
<ParallaxSection container={scrollerRef}>{/* … */}</ParallaxSection>
</div>;Props
ParallaxSection
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
children | ReactNode | — | 一或多個 ParallaxLayer |
range | number | 120 | 每單位 speed 對應的最大視差位移距離(px) |
container | RefObject<HTMLElement | null> | — | 巢狀捲動容器的 ref;未提供時以視窗為捲動容器 |
className | string | — | 附加的 class(預設帶 relative overflow-hidden) |
其餘 React.HTMLAttributes<HTMLElement>(如 aria-label、style、id)會轉傳到根 <section>。
ParallaxLayer
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
children | ReactNode | — | 該層內容 |
speed | number | 0.5 | 位移倍率;正值偏前景(較快、逆向上浮),負值偏後景(較慢、順向下沉),0 無視差 |
axis | "x" | "y" | "y" | 位移軸向 |
fade | boolean | false | 在區塊進出視口兩端淡入淡出 |
decorative | boolean | false | 標記為純裝飾層(加 aria-hidden、停用指標事件) |
className | string | — | 附加的 class |
細節
- 進度以
useScroll追蹤區塊由「底部進入視口」到「頂部離開視口」的整段捲動(offset: ["start end", "end start"]),中點0.5為區塊置中、各層回到自然位置。 - 每層位移為
progress在[+speed·range, -speed·range]間的線性映射,因此區塊置中時位移為 0,向兩端漸增。 - 視差層通常以
absolute inset-0疊放;請在ParallaxSection設定明確高度,並保留預設的overflow-hidden以裁切超出的背景。 speed的正負決定景深方向,數值大小決定位移幅度;建議背景層用較小的負值、前景強調層用較大的正值。
可及性
- 使用者系統開啟「減少動態效果」時,自動停用視差位移與淡出,各層固定於自然位置,內容維持完整可讀。
- 純裝飾層請加上
decorative,會套用aria-hidden並停用指標事件,避免輔助科技朗讀與誤觸。 - 視差僅套用
transform/opacity,不影響文件流與朗讀順序。