Navigation✨ Premium

Sticky Header Detection

Header sticky piloté par l'attribut data-stuck : à 10 px de scroll, fond plus opaque, ombre portée et logo accentué — transition CSS pure, aucune dépendance.

JSStickyObserver

Vous aurez accès à la démo interactive avec un compte gratuit.

Cet effet fait partie d'Effect.Labs — 811 effets vanilla, une partie gratuite, une partie premium. Navigation comprend 36 effets, dont 4 gratuits. Découvrir la catégorie →

3 exemples d'usage

Landing page produit — Header ghost qui se solidifie au premier scroll — Sticky Header Detection exemple 1

① Landing page produit — Header ghost qui se solidifie au premier scroll

QuandPage d'accueil avec un hero plein écran : le visiteur arrive sur une section immersive avant de découvrir le contenu produit en scrollant.
PourquoiL'état initial semi-transparent laisse la typographie du hero respirer ; dès 10 px de défilement, le fond s'opacifie et l'ombre portée apparaît — le header prend de l'autorité exactement au moment où l'utilisateur s'engage avec le contenu.
RéglagesRéduire rgba(18,18,26,.8) à rgba(18,18,26,.4) pour un ghost plus prononcé sur un hero coloré ; conserver le seuil 10 px et le backdrop-filter: blur(10px) pour le flou de profondeur.
Site de documentation — Header qui prend de l'importance à la lecture — Sticky Header Detection exemple 2

② Site de documentation — Header qui prend de l'importance à la lecture

QuandPage de documentation ou de blog longue : le lecteur commence en haut puis fait défiler pour lire l'article, perdant de vue le contexte de navigation.
PourquoiLa présence renforcée du header (fond plus opaque, ombre légère) rappelle discrètement la marque et les liens de navigation sans ralentir le regard sur le contenu technique.
RéglagesRéduire la box-shadow à 0 2px 8px rgba(0,0,0,0.2) pour un rendu plus discret ; adapter rgba(18,18,26,0.95) à la couleur principale du site.
Boutique en ligne — Barre de navigation persistante au scroll catalogue — Sticky Header Detection exemple 3

③ Boutique en ligne — Barre de navigation persistante au scroll catalogue

QuandPage catalogue ou fiche produit longue : le visiteur fait défiler les articles et doit retrouver facilement la navigation et l'icône panier.
PourquoiL'effet matérialise visuellement que la navigation est « fixée » dès 10 px de scroll — feedback rassurant pour un visiteur qui explore un catalogue dense.
RéglagesAjouter une icône panier avec badge dans .nav-links-mini ; augmenter le seuil à 30 px si un hero image occupe le haut de la page.

Comment ça marche

L'effet écoute l'événement scroll nativement sur l'élément #scrollArea — sans IntersectionObserver. Dès que le scrollTop du conteneur dépasse 10 px, le script pose data-stuck="true" sur #stickyNav ; en deçà, il repasse à "false". Un seul setAttribute par événement scroll, aucun debounce.

La réponse visuelle est entièrement pilotée par CSS via le sélecteur d'attribut [data-stuck=true]. Le JS ne touche ni à des classes ni à du style inline : il écrit un attribut, la feuille de style réagit. Ce découplage permet de redéfinir l'aspect « collé » sans jamais modifier la logique de détection.

À l'état collé, trois transitions CSS de 0,3 s se déclenchent simultanément : l'arrière-plan monte de rgba(18,18,26,0.8) à rgba(18,18,26,0.95), une box-shadow de 20 px apparaît, et la bordure basse passe de transparent à var(--border). Le logo reçoit en plus transform: scale(1.05) et change de couleur vers #6366f1 — signal discret que la navigation est maintenant ancrée.

Le conteneur combine overflow: hidden et position: relative ; la nav est en position: absolute — elle ne déborde jamais. Un backdrop-filter: blur(10 px) constant donne au header un aspect verre dépoli même avant le premier pixel de scroll, rendant l'ensemble autonome et intégrable dans n'importe quelle mise en page.

Accessibilité

  • prefers-reduced-motion absent : la transition: .3s sur .sticky-nav s'exécute sans consulter la préférence système. Pour les utilisateurs sensibles au mouvement, enveloppez les transitions dans @media (prefers-reduced-motion: no-preference).
  • Aucun role ni aria-label sur le header : en production, ajoutez role="navigation" et un aria-label descriptif sur l'élément de navigation.
  • L'attribut data-stuck est un hook CSS pur, non annoncé aux technologies d'assistance — le changement visuel est décoratif et ne véhicule pas d'état fonctionnel.
  • Les liens de navigation sont des <span> dans la démo : remplacez-les par des <a> pour que la navigation au clavier et les lecteurs d'écran fonctionnent correctement.
  • Contraste : le logo passe en #6366f1 sur fond #12121a au scroll — ratio ≈ 4,5:1, à la limite du seuil WCAG AA pour le texte de petite taille ; vérifiez votre couleur brand.

Compatibilité navigateur

Requiert scroll event, sélecteurs d'attribut CSS et backdrop-filter — les deux premiers sont universels depuis IE9+ ; backdrop-filter est supporté dans tous les navigateurs modernes.

Chrome 76+✓ Complet
Firefox 103+✓ Complet
Safari 9+✓ Complet
Edge 79+✓ Complet
Mobile iOS✓ Complet
Android Chrome✓ Complet

Si <code>backdrop-filter</code> n'est pas supporté, le header s'affiche avec son fond plein — aucune erreur JS, la détection de scroll fonctionne normalement.

Le code

Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :

index.html — structure
<div class="sticky-header-demo" id="stickyDemo">
  <div class="sticky-nav" id="stickyNav">
    <span class="nav-logo-mini">Brand</span>
    <div class="nav-links-mini">
      <span>Home</span>
      <span>About</span>
      <span>Contact</span>
    </div>
  </div>
  <div class="scroll-area" id="scrollArea">
    <div class="scroll-content">
      <!-- contenu scrollable -->
    </div>
  </div>
</div>
🔒 Débloquer le code complet — à partir de 2,99 € le 1er mois

HTML + CSS + JS complet, prêt à coller — avec des centaines d'effets premium.

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
s.scrollTop > 10 10 Seuil en pixels au-delà duquel data-stuck passe à true. Remplacez 10 par 0 pour déclencher dès le premier pixel, ou 50–80 si un hero occupe toute la hauteur visible.
transition: .3s .3s Durée de toutes les transitions du header (fond, ombre, bordure). Passez à 0s pour un snap instantané ou 0.5s pour une fondu plus doux.
rgba(18, 18, 26, .8) alpha 0.8 Opacité du fond nav à l'état initial (non collé). Montez à 1 pour un fond plein dès le départ, descendez à 0.4 pour plus de transparence.
rgba(18, 18, 26, .95) alpha 0.95 Opacité du fond nav à l'état collé (data-stuck=true). Adaptez la couleur de base à votre palette brand.
box-shadow: rgba(0,0,0,.3) 0 4px 20px 4px / 20px Ombre portée à l'état collé. Réduisez la taille (2px / 8px) pour un rendu subtil, supprimez entièrement pour un effet 100 % couleur.
color: #6366f1 #6366f1 Couleur du logo quand le header est collé. Remplacez par votre couleur primaire pour un signal de branding discret.
backdrop-filter: blur(10px) 10px Flou d'arrière-plan constant du header. Réduisez à 4px pour un effet plus léger, supprimez la propriété pour économiser du GPU sur des appareils bas de gamme.

FAQ

Non — la détection repose sur un listener scroll classique qui lit scrollTop > 10. L'IntersectionObserver cible le viewport global ; ici la zone scrollable est un conteneur interne, ce qui rend le scroll event plus direct et plus fiable dans ce contexte.
Remplacez le listener sur #scrollArea par window.addEventListener('scroll', …) et comparez window.scrollY > 10. Le reste — attribut data-stuck et CSS — reste identique. Passez le header en position: fixed et retirez overflow: hidden du conteneur parent.
Oui : après avoir déclaré le listener, appelez s.dispatchEvent(new Event('scroll')) pour forcer une première évaluation de scrollTop. Cela garantit que data-stuck est correct même si la page est rechargée à mi-scroll ou si le conteneur a déjà un offset initial.