WebberUI

Scroll-aware Navbar

會隨滾動收縮、隱藏或變寬的導航列,三種樣式共用一致的節奏並支援巢狀捲動容器。

載入預覽⋯

Playground

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

24
72
56
448
<ScrollAwareNavbar />

安裝

npx shadcn@latest add https://webberui.com/r/scroll-aware-navbar.json

或在 components.json 設定 registries 後,改用 @webberui/scroll-aware-navbar 安裝。

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

npm install motion clsx tailwind-merge

使用

import { ScrollAwareNavbar } from "@/components/ui/scroll-aware-navbar";

<ScrollAwareNavbar variant="shrink">
  <span className="font-semibold">Webber</span>
  <nav className="flex gap-4">
    <a href="#features">功能</a>
    <a href="#docs">文件</a>
  </nav>
  <button className="rounded-full bg-neutral-900 px-3 py-1.5 text-white">
    開始
  </button>
</ScrollAwareNavbar>

導航列以 sticky top-0 貼齊捲動容器頂部,children 由你自由排版(預設 justify-between)。若捲動發生在巢狀 overflow 容器內,將該容器的 ref 傳入 container

const scrollerRef = React.useRef<HTMLDivElement>(null);

<div ref={scrollerRef} className="h-[400px] overflow-y-auto">
  <ScrollAwareNavbar variant="float" container={scrollerRef}>
    {/* ... */}
  </ScrollAwareNavbar>
  {/* 內容 */}
</div>

Props

Prop型別預設值說明
childrenReact.ReactNode導航列內容,通常為品牌、連結與行動按鈕
variant"shrink" | "hide" | "float""shrink"滾動反應樣式:收縮、隱藏、或變寬
thresholdnumber24判定為「已滾動」的門檻(px)
expandedHeightnumber72置頂時的展開高度(px)
condensedHeightnumber56滾動後的收縮高度(px),供 shrink 與 float 使用
pillWidthnumber448float 樣式置頂時的膠囊寬度上限(px)
position"sticky" | "fixed""sticky"定位方式;fixed 需自行為內容預留空間
containerRefObject<HTMLElement | null>巢狀捲動容器的 ref;未傳入時追蹤整個視窗
classNamestring套用在可視導航列(內層 bar)上,可加 max-w、字級等
wrapperClassNamestring套用在最外層定位容器(header)上,例如覆寫 z-index
aria-labelstring"主導航列"導航列 landmark 的無障礙標籤

三種樣式

  • shrink:置頂時透明地浮在內容之上;滾動超過 threshold 後高度由 expandedHeight 收縮到 condensedHeight,並淡入毛玻璃背景與底線。
  • hide:向下滾動時整條以位移收起、向上滾動時滑回,適合讓內容區在閱讀時佔滿高度。滾動後同樣浮現背景。
  • float:置頂時是一顆置中的窄膠囊(pillWidth)並與頂端保留間距;滾動後變寬鋪滿容器、圓角收斂並貼齊頂部。

細節

  • useScroll 追蹤捲動位置,hide 樣式再比對前後位移判斷方向;含 2px 死區避免抖動。
  • float 的變寬目標寬度以 ResizeObserver 量測外層容器實際寬度取得,因此展寬動畫平滑且隨容器尺寸自適應。
  • 背景以獨立圖層淡入淡出,收縮或浮現時不牽動內容排版。

可及性

  • 最外層為 <header> landmark 並帶 aria-labelhide 樣式收起後,鍵盤焦點一旦移入導航列會立即滑回,焦點不會停在畫面外。
  • 使用者系統開啟「減少動態效果」時,停用向下捲動的位移隱藏(導航列恆為可見),其餘狀態改為即時切換而非過渡動畫。
  • 所有 useScroll 事件監聽與 ResizeObserver 於 unmount 時完整清理。

On this page