Headers
24 patrones reales de header — desktop + responsive. Cada uno copy-pasteable.
Marketing
Simple
Logo · nav inline · CTA. El más usado en marketing landings.
📱 Mobile: nav colapsa a hamburger drawer.
▸ Ver código▾ Ocultar código
<header className="border-b bg-bg">
<div className="max-w-6xl mx-auto px-4 h-14 flex items-center justify-between">
<Logo />
<nav className="hidden md:flex gap-1 text-sm">
{LINKS.map(l => <a href={l.href}>{l.label}</a>)}
</nav>
<div className="flex gap-2">
<Button variant="ghost" size="sm" className="hidden md:inline-flex">Entrar</Button>
<Button size="sm">Empezar</Button>
<MobileDrawer />
</div>
</div>
</header>Centered Nav
Nav centrada en grid de 3 columnas. Sensación premium.
📱 Mobile: nav y CTAs van al drawer.
▸ Ver código▾ Ocultar código
<div className="max-w-6xl mx-auto px-4 h-14 grid md:grid-cols-3 items-center">
<Logo />
<nav className="hidden md:flex justify-center gap-1">{...LINKS}</nav>
<div className="hidden md:flex justify-end gap-2"><Button>...</Button></div>
</div>Logo en el centro
Magazine-style. Logo destacado en el medio, nav split.
📱 Mobile: nav completo en drawer.
▸ Ver código▾ Ocultar código
<div className="max-w-6xl mx-auto h-16 grid md:grid-cols-3 items-center">
<nav>{LINKS.slice(0,2).map(...)}</nav>
<div className="md:flex md:justify-center"><Logo /></div>
<nav>{LINKS.slice(2).map(...)}</nav>
</div>Mega Menu
Dropdown grande con 2 columnas + iconos. Stripe/Linear style.
📱 Mobile: el mega menu se aplana en el drawer.
▸ Ver código▾ Ocultar código
<Menu>
<MenuTrigger render={
<button className="px-3 py-1.5 inline-flex items-center gap-1">
Producto <ChevronDown />
</button>
} />
<MenuContent className="w-[520px] p-4">
<div className="grid grid-cols-2 gap-x-8">
{COLUMNS.map(c => (
<a className="flex gap-3 p-2 rounded-md hover:bg-bg-subtle">
<span>{c.icon}</span>
<div>
<div className="text-sm font-medium">{c.title}</div>
<div className="text-xs text-fg-muted">{c.desc}</div>
</div>
</a>
))}
</div>
</MenuContent>
</Menu>Floating Pill
Flotante separado del top, rounded full. Vibe moderna/indie.
📱 Mantiene su forma, drawer en mobile.
▸ Ver código▾ Ocultar código
<div className="pt-4 px-4">
<header className="max-w-3xl mx-auto rounded-full border bg-bg-elevated/80 backdrop-blur shadow-sm">
<div className="px-3 h-12 flex items-center justify-between gap-3">
<Logo size="sm" />
<nav>...</nav>
<Button size="sm" className="rounded-full">Empezar</Button>
</div>
</header>
</div>Con barra de anuncio
Anuncio dismissible arriba + header debajo.
📱 La barra se mantiene en mobile (texto se hace más corto).
▸ Ver código▾ Ocultar código
const [show, setShow] = useState(true);
{show && (
<div className="bg-primary text-primary-fg text-xs">
<div className="max-w-6xl mx-auto px-4 h-9 flex items-center justify-between">
<span>📢 Mensaje aquí. <a className="underline">Ver →</a></span>
<button onClick={() => setShow(false)}><X /></button>
</div>
</div>
)}
<header>...</header>Floating
Glass / Glassmorphism
Backdrop blur fuerte con borde semi-transparente. Estilo Apple/Liquid.
📱 Funciona mejor sobre contenido detrás (hero con imagen).
▸ Ver código▾ Ocultar código
<header className="sticky top-0 z-30 bg-bg/30 backdrop-blur-xl border-b border-white/10">
<div className="max-w-6xl mx-auto px-4 h-14 flex items-center justify-between">
<Logo />
<nav>...</nav>
<Button size="sm" className="backdrop-blur">Empezar</Button>
</div>
</header>Apple Dock
Dock flotante abajo con magnify on hover. macOS / iPadOS style.
📱 Trabaja en cualquier ancho — los iconos crecen al hover.
▸ Ver código▾ Ocultar código
<nav className="fixed bottom-4 inset-x-0 flex justify-center">
<div className="flex items-end gap-1.5 px-3 py-2 rounded-2xl bg-bg-elevated/70 backdrop-blur-xl border shadow-lg">
{items.map(it => (
<button className="grid place-items-center h-11 w-11 rounded-xl bg-bg hover:scale-125 hover:-translate-y-1 transition-all">
{it.icon}
</button>
))}
</div>
</nav>Dynamic Island
Pill negro centrado top, expandible al click. Inspirado iOS.
📱 Centro siempre — se adapta al contenido.
▸ Ver código▾ Ocultar código
const [expanded, setExpanded] = useState(false);
<header className="absolute top-3 inset-x-0 flex justify-center">
<button
onClick={() => setExpanded(v => !v)}
className={cn(
"flex items-center gap-3 bg-iron-950 text-iron-50 transition-all duration-300 shadow-lg",
expanded ? "h-20 px-5 rounded-3xl w-[420px]" : "h-9 px-4 rounded-full"
)}
>...</button>
</header>Floating Sidebar Rail
Rail vertical flotante a la izquierda, icon-only. Para apps con muchas pantallas.
📱 Mantener fixed; en mobile colapsar a bottom tabs.
▸ Ver código▾ Ocultar código
<aside className="fixed left-3 top-3 bottom-3 w-14 rounded-xl bg-bg-elevated border shadow-md flex flex-col items-center py-3 gap-1">
<Logo />
{items.map((Icon, i) => (
<button className="grid place-items-center h-9 w-9 rounded-md hover:bg-bg-subtle">
<Icon className="h-4 w-4" />
</button>
))}
<Avatar className="mt-auto" />
</aside>Floating Bottom Pill
Pill oscuro flotante abajo con tabs + acción primaria (FAB style).
📱 Perfecto para mobile y PWA. Se mantiene en desktop también.
▸ Ver código▾ Ocultar código
<nav className="fixed bottom-4 inset-x-0 flex justify-center">
<div className="flex items-center gap-1 px-1.5 py-1.5 rounded-full bg-iron-950 text-iron-50 shadow-lg">
{tabs.map(t => (
<button onClick={() => setActive(t.id)} className={cn(
"flex items-center gap-1.5 h-8 px-3 rounded-full",
active === t.id ? "bg-primary text-primary-fg" : "text-iron-300"
)}>{t.icon}{t.label}</button>
))}
<span className="w-px h-5 bg-iron-800 mx-1" />
<button className="grid place-items-center h-8 w-8 rounded-full bg-primary"><Plus /></button>
</div>
</nav>Spotlight Trigger
Solo trigger ⌘K flotante en top-center. Minimalismo extremo.
📱 Se adapta al ancho disponible (max 440px).
▸ Ver código▾ Ocultar código
<header className="absolute top-4 inset-x-0 flex justify-center">
<button className="flex items-center justify-between gap-3 w-[min(440px,calc(100%-2rem))] h-10 px-3 rounded-full bg-bg-elevated/80 backdrop-blur-xl border shadow-md">
<span className="flex items-center gap-2">
<Logo size="sm" />
<span>Buscar componentes, blocks, docs…</span>
</span>
<kbd>⌘K</kbd>
</button>
</header>Behavioral
Transparent → Solid on scroll
Transparente sobre el hero. Se vuelve sólido al hacer scroll.
📱 Funciona en todos los tamaños — depende del hero detrás.
▸ Ver código▾ Ocultar código
// lib/scroll.ts
export function useScrolled(threshold = 8) {
const [scrolled, setScrolled] = useState(false);
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > threshold);
onScroll();
window.addEventListener("scroll", onScroll, { passive: true });
return () => window.removeEventListener("scroll", onScroll);
}, [threshold]);
return scrolled;
}
// header
const scrolled = useScrolled(8);
<header className={cn(
"sticky top-0 z-30 transition-colors",
scrolled ? "bg-bg/80 backdrop-blur border-b" : "bg-transparent"
)}>...</header>Hide on scroll down
Se oculta al scroll hacia abajo y reaparece al subir. Medium/Twitter style.
📱 Especialmente útil en mobile (recupera espacio).
▸ Ver código▾ Ocultar código
// lib/scroll.ts
export function useHideOnScroll() {
const [hide, setHide] = useState(false);
useEffect(() => {
let last = 0;
const onScroll = () => {
const y = window.scrollY;
setHide(y > 64 && y > last);
last = y;
};
window.addEventListener("scroll", onScroll, { passive: true });
return () => window.removeEventListener("scroll", onScroll);
}, []);
return hide;
}
const hide = useHideOnScroll();
<header className={cn(
"sticky top-0 z-30 transition-transform",
hide ? "-translate-y-full" : "translate-y-0"
)}>...</header>Two-row collapsing
2 filas (logo+actions / nav) → colapsa a 1 al scrollar. Nike-style.
📱 El segundo row siempre se oculta en mobile (categorías al drawer).
▸ Ver código▾ Ocultar código
const collapsed = useScrolled(20);
<header className="sticky top-0 bg-bg border-b">
<div className={cn("flex items-center justify-between transition-all", collapsed ? "h-12" : "h-14")}>
<Logo size={collapsed ? "sm" : "md"} />
<div className="flex gap-2"><Button>Buscar</Button><Button>Cuenta</Button></div>
</div>
<div className={cn("overflow-hidden transition-all border-t", collapsed ? "h-0 border-t-0" : "h-10")}>
<nav>{CATEGORIES.map(...)}</nav>
</div>
</header>Reading Progress
Header sticky + barra de progreso de lectura abajo. Blogs / artículos largos.
📱 El título central se oculta en mobile.
▸ Ver código▾ Ocultar código
// lib/scroll.ts
export function useScrollProgress() {
const [pct, setPct] = useState(0);
useEffect(() => {
const onScroll = () => {
const h = document.documentElement;
const max = h.scrollHeight - h.clientHeight;
setPct(max > 0 ? (h.scrollTop / max) * 100 : 0);
};
onScroll();
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, []);
return pct;
}
const pct = useScrollProgress();
<header className="sticky top-0">
...
<div className="absolute bottom-0 inset-x-0 h-0.5 bg-bg-subtle">
<div className="h-full bg-primary" style={{ width: pct + "%" }} />
</div>
</header>App
Dashboard Topbar
Search + notifs + user menu. Pensado con sidebar a la izquierda.
📱 Mobile: aparece botón hamburger para abrir sidebar; search se oculta.
▸ Ver código▾ Ocultar código
<header className="border-b bg-bg-elevated">
<div className="px-4 h-14 flex items-center justify-between gap-4">
<div className="flex items-center gap-3">
<Button variant="ghost" size="icon" className="md:hidden"><MenuIcon /></Button>
<Logo size="sm" />
<span className="hidden md:inline">/ Acme Corp</span>
</div>
<div className="hidden md:block flex-1 max-w-md mx-4 relative">
<Search /> <Input className="pl-9" placeholder="Buscar…" />
</div>
<div className="flex items-center gap-1">
<Button variant="ghost" size="icon"><Bell /></Button>
<Menu>
<MenuTrigger render={<button><Avatar fallback="RF" /></button>} />
<MenuContent>
<MenuLabel>Mi cuenta</MenuLabel>
<MenuItem>Perfil</MenuItem>
<MenuItem>Cerrar sesión</MenuItem>
</MenuContent>
</Menu>
</div>
</div>
</header>Command Palette CTA
Botón ⌘K dominante. Linear/Vercel style.
📱 El kbd se oculta en pantallas muy pequeñas.
▸ Ver código▾ Ocultar código
<button className="flex-1 max-w-md inline-flex items-center justify-between px-3 h-9 rounded-md border bg-bg text-sm text-fg-muted hover:border-border-strong">
<span className="flex items-center gap-2"><Command /> Buscar o ejecutar comando…</span>
<kbd>⌘K</kbd>
</button>Page Header (interno)
Breadcrumb + título + descripción + actions. Para pantallas internas.
📱 Actions se apilan debajo del título en mobile.
Settings
Gestiona la configuración de tu workspace.
▸ Ver código▾ Ocultar código
<header className="border-b bg-bg-elevated">
<div className="px-6 py-4 flex flex-col md:flex-row md:items-end md:justify-between gap-3">
<div>
<nav className="flex items-center gap-1 text-xs text-fg-muted mb-1">
<a>Proyectos</a> / <a>Acme Corp</a> / <span>Settings</span>
</nav>
<h1 className="text-2xl font-semibold">Settings</h1>
<p className="text-sm text-fg-muted">Descripción.</p>
</div>
<div className="flex items-center gap-2">
<Button variant="outline" size="sm">Exportar</Button>
<Button size="sm">Guardar</Button>
</div>
</div>
</header>Sticky Secondary CTA
Header principal + segunda barra sticky con producto + acción persistente. E-commerce / pricing.
📱 El precio se oculta en pantallas muy pequeñas.
▸ Ver código▾ Ocultar código
<header>...</header>
<div className="sticky top-0 bg-bg-elevated/95 backdrop-blur border-b shadow-sm">
<div className="h-14 flex items-center justify-between gap-4">
<div className="flex items-center gap-3">
<span className="h-9 w-9 rounded-md bg-bg-subtle"><Package /></span>
<div>
<div className="text-sm font-medium">Lenovo IdeaPad 5</div>
<div className="text-xs text-fg-muted">SKU LP5-i7 · stock</div>
</div>
</div>
<div className="flex items-center gap-3">
<span className="text-lg font-semibold">S/. 3,490</span>
<Button>Añadir al carrito</Button>
</div>
</div>
</div>Specialized
Search-Led (Docs)
Búsqueda dominante centrada. Docs sites, help centers.
📱 El search ocupa todo el ancho disponible en mobile.
▸ Ver código▾ Ocultar código
<header className="border-b">
<div className="max-w-6xl mx-auto px-4 h-14 flex items-center gap-4">
<Logo />
<div className="flex-1 max-w-xl mx-auto relative">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-fg-muted" />
<Input className="pl-9" placeholder="Buscar…" />
<kbd className="absolute right-2 top-1/2 -translate-y-1/2">⌘K</kbd>
</div>
<nav>...</nav>
</div>
</header>E-commerce 3-tier
Anuncio + main (logo+search+cart) + categorías. Patrón clásico de tiendas.
📱 Mobile: search se oculta del tier 2, categorías se ocultan completas.
▸ Ver código▾ Ocultar código
<div>
{/* Tier 1 */}
<div className="bg-iron-900 text-iron-50 text-xs">
<div className="max-w-7xl mx-auto h-9 flex items-center justify-center">
Envío gratis · Compras +S/. 200
</div>
</div>
{/* Tier 2 */}
<div className="border-b">
<div className="max-w-7xl mx-auto h-16 flex items-center justify-between gap-6">
<Logo />
<div className="hidden md:flex flex-1 max-w-xl"><Input rounded-full /></div>
<div className="flex gap-1">
<Button size="icon"><Heart /></Button>
<Button size="icon"><User /></Button>
<Button size="icon"><ShoppingCart /><Badge>3</Badge></Button>
</div>
</div>
</div>
{/* Tier 3 */}
<div className="hidden md:block border-b bg-bg-elevated">
<div className="max-w-7xl mx-auto h-10 flex items-center gap-1 overflow-x-auto">
{CATEGORIES.map(c => <a>{c}</a>)}
</div>
</div>
</div>Mobile
Mobile Bottom Tabs
5 destinos primarios fijos abajo + topbar mínimo. PWA / mobile-first.
📱 Solo mobile — en desktop usar sidebar tradicional.
▸ Ver código▾ Ocultar código
<div className="relative pt-14 pb-20 min-h-screen">
<header className="absolute top-0 inset-x-0 border-b h-14 flex items-center justify-between px-4">
<Logo size="sm" /> <Button size="icon"><MenuIcon /></Button>
</header>
<main>{children}</main>
<nav className="absolute bottom-0 inset-x-0 border-t bg-bg-elevated">
<div className="grid grid-cols-5 h-16">
{tabs.map(t => (
<button onClick={() => setActive(t.id)} className={cn(
"flex flex-col items-center justify-center gap-0.5",
active === t.id ? "text-primary" : "text-fg-muted"
)}>
<t.icon className="h-5 w-5" />
<span className="text-[10px]">{t.label}</span>
</button>
))}
</div>
</nav>
</div>