PC07▸🧭 Navigation · 導航▸導航列
Resizable Navbar
縮放導航列
難度 ★★★★★標籤 scroll · shrink · sticky3 min read
模式簡述
Resizable Navbar:捲動後 navbar 變窄、變透明、變膠囊。Vercel、Linear 都這麼做。視覺上節省空間。
scroll 前:navbar 鬆散,跟頁面融合
Claude Code Prompt
參考:PC07 resizable-navbar 組件:ResizableNavbar.tsx Resizable Navbar:捲動後 navbar 變窄、變透明、變膠囊。Vercel、Linear 都這麼做。視覺上節省空間。 限制: - transition 沒寫,直接跳 - 收縮後 nav 內容塞不下 - scroll listener 沒做 throttle
完整程式碼
"use client";
import { useEffect, useState } from "react";
import { cn } from "@/lib/utils";
type State = "top" | "scrolled";
export function ResizableNavbar({ state = "top" }: { state?: State }) {
const [scrolled, setScrolled] = useState(state === "scrolled");
useEffect(() => setScrolled(state === "scrolled"), [state]);
return (
<div className="relative h-[260px] w-full max-w-md overflow-hidden rounded-lg border border-border bg-background/30">
<nav
className={cn(
"absolute inset-x-3 top-3 z-10 flex items-center justify-between rounded-full border transition-all duration-300",
scrolled
? "border-border bg-background/80 px-3 py-1.5 backdrop-blur-xl shadow-md"
: "border-transparent bg-transparent px-4 py-3",
)}
>
<span
className={cn(
"font-mono font-medium transition-all",
scrolled ? "text-xs" : "text-sm",
)}
>
Frontend Lab
</span>
<div className={cn("flex items-center gap-1 transition-all", scrolled && "scale-90")}>
<a className="rounded-full px-2.5 py-1 text-[11px] text-muted-foreground hover:text-foreground">
效果
</a>
<a className="rounded-full px-2.5 py-1 text-[11px] text-muted-foreground hover:text-foreground">
模式
</a>
<button
className={cn(
"rounded-full bg-lab-accent text-background transition-all",
scrolled ? "px-2.5 py-1 text-[11px]" : "px-3 py-1.5 text-xs",
)}
>
開始
</button>
</div>
</nav>
<div className="absolute inset-x-0 top-20 px-4 text-center text-xs text-muted-foreground">
{scrolled ? "scroll 後:navbar 縮小 + backdrop blur" : "scroll 前:navbar 鬆散,跟頁面融合"}
</div>
</div>
);
}何時用
- ✅ 長頁面 marketing site
- ✅ 需要 sticky 但又不想擋內容
- ✅ 想做高質感的 brand 站
何時別用
- ❌ 後台應用(功能型介面別玩花樣)
- ❌ 資訊密集的 doc 站
- ❌ 原本 navbar 很簡單時(沒必要)
我踩過的坑
-
transition 沒寫,直接跳:要 transition-all 300ms。
-
收縮後 nav 內容塞不下:要規劃好收縮狀態的版面,不是只縮高度。
-
scroll listener 沒做 throttle:每 px 重 render,60fps 卡。用 useScroll + threshold。
相關模式
- PC03
- PC06