Parent : [[INDEX-WEB-UIUX]]
Web UI/UX - Sticky Glassmorphism Header : backdrop-filter blur, border-bottom, z-index
Problème
Un header fixe sans transparence crée une barre opaque moche qui masque le contenu en dessous. Un header transparent sans blur rend le texte illisible sur du contenu complexe.
Solution
Header sticky (pas fixed) avec backdrop-filter: blur(12px) et fond semi-transparent, border-bottom subtil, et z-index: 40.
<header
className="sticky top-0 z-40"
style={{
background: 'rgba(10, 11, 13, 0.92)',
borderBottom: '1px solid var(--border)',
backdropFilter: 'blur(12px)',
WebkitBackdropFilter: 'blur(12px)',
}}
>
<div className="max-w-[1600px] mx-auto px-6 h-14 flex items-center justify-between gap-8">
{/* Logo */}
<div className="flex items-center gap-3 shrink-0">
<div
className="w-7 h-7 rounded-[4px] flex items-center justify-center text-white font-black text-sm"
style={{ background: 'var(--accent)' }}
>
F
</div>
<span className="font-bold text-sm tracking-wide">
BRAND<span style={{ color: 'var(--accent)' }}>NAME</span>
</span>
</div>
{/* Nav desktop */}
<nav className="hidden sm:flex items-center gap-1">
{NAV.map((item) => {
const active = section === item.id
return (
<button
key={item.id}
onClick={() => setSection(item.id)}
className="px-4 py-2 rounded-[4px] text-xs font-semibold tracking-wide uppercase transition-colors"
style={active
? { background: 'var(--accent-dim)', color: 'var(--accent)', border: '1px solid rgba(229,25,26,0.25)' }
: { background: 'transparent', color: 'var(--text-2)', border: '1px solid transparent' }
}
onMouseEnter={(e) => { if (!active) e.currentTarget.style.color = 'var(--text)' }}
onMouseLeave={(e) => { if (!active) e.currentTarget.style.color = 'var(--text-2)' }}
>
{item.label}
</button>
)
})}
</nav>
{/* Mobile nav (scroll-x) */}
<div className="sm:hidden flex overflow-x-auto px-4 pb-2 gap-1 border-t" style={{ borderColor: 'var(--border)' }}>
{NAV.map((item) => (
<button
key={item.id}
onClick={() => setSection(item.id)}
className="px-3 py-1.5 rounded-[4px] text-xs font-semibold whitespace-nowrap uppercase shrink-0"
style={section === item.id
? { background: 'var(--accent-dim)', color: 'var(--accent)' }
: { color: 'var(--text-2)' }
}
>
{item.label}
</button>
))}
</div>
</div>
</header>
Points clés
stickypasfixed: évite de sortir le header du flow, pas besoin depadding-topsur le bodybackdropFilter: blur(12px): minimum 8px pour être visible, 12-16px pour un effet propre- Fond
rgba(..., 0.92): pas 100% transparent (illisible) ni 100% opaque (moche) z-40: au-dessus du contenu (z-30) mais en dessous des modals (z-50)- Nav desktop + mobile : desktop = flex hidden sm:flex, mobile = flex overflow-x-auto sm:hidden
Pourquoi
stickyest plus performant et moins bugué quefixedsur mobilebackdrop-filtercrée une sensation de profondeur sans masquer le contenu- Le pattern desktop/mobile garantit l'accessibilité sur tous les écrans
Quand l'utiliser
- Dashboard, SaaS, applications web avec navigation
- Sites avec du contenu scrollable long
Quand NE PAS l'utiliser
- Landing page one-page avec ancre scroll (pas besoin de sticky)
- Si le support navigateur doit être IE11 (pas de backdrop-filter)
Références
- ProjectAlpha/page.tsx L33-99