Navigation✨ Premium

Pill Indicator

Pastille animée qui glisse vers l'onglet actif avec un rebond élastique — position calculée en temps réel via getBoundingClientRect, items ajoutables librement.

JSTab

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

Navigation principale — Tableau de bord SaaS — Pill Indicator exemple 1

① Navigation principale — Tableau de bord SaaS

QuandL'interface expose plusieurs sections (Accueil, Statistiques, Paramètres) accessibles depuis un seul rail horizontal en haut de page.
PourquoiLa pastille glissante rend la section active évidente d'un coup d'œil et confirme chaque clic avec un micro-rebond — bien plus expressif qu'un simple changement de couleur ou de souligné.
Réglages3 à 5 items, background de .pill-indicator aligné sur la couleur brand, transition .25s pour une réactivité optimale, --bg-card légèrement plus sombre que le fond de page.
Filtre de période — Vue analytics — Pill Indicator exemple 2

② Filtre de période — Vue analytics

QuandUn tableau ou un graphique expose plusieurs granularités temporelles (Jour / Semaine / Mois / Année) que l'utilisateur bascule fréquemment sans naviguer.
PourquoiLa pastille crée un retour visuel immédiat sur la période sélectionnée ; son rebond distingue le clic d'un simple survol et évite toute confusion sur l'état actif.
Réglages4 items courts, padding réduit (0.4rem 1rem) pour compacité, --radius-full: 8px pour un look onglet rectangulaire, transition .2s ease-out sans rebond pour une UI de données.
Toggle de plan tarifaire — Mensuel / Annuel — Pill Indicator exemple 3

③ Toggle de plan tarifaire — Mensuel / Annuel

QuandUne section de tarification propose deux cycles de facturation ; le toggle pill bascule l'affichage des prix sans recharger la page.
PourquoiLe glissement élastique attire l'œil vers l'option choisie et donne l'impression d'un contrôle physique — l'overshoot de la courbe back-out rend le choix tangible et mémorisable.
Réglages2 items uniquement, background de .pill-indicator en vert émeraude (#10b981) pour signaler l'économie, chaque item occupe ~50 % de la largeur du conteneur.

Comment ça marche

L'indicateur (.pill-indicator) est un <div> absolument positionné à l'intérieur du .pill-nav en position: relative. Quand un item est cliqué, le script lit getBoundingClientRect() de l'item et du conteneur, calcule la différence de left et copie le width — puis assigne ces deux valeurs en px sur les styles left et width de l'indicateur. CSS transition prend ensuite le relais pour animer le déplacement.

La transition porte la courbe cubic-bezier(0.175, 0.885, 0.32, 1.275) sur .3s — un easing de type back-out qui génère un léger dépassement (overshoot) avant de se stabiliser, d'où l'effet rebond sans aucune physique JS. Modifier uniquement la durée ou substituer ease-out supprime ce rebond.

Les .pill-link (spans) ont position: relative; z-index: 1 pour rester visuellement au-dessus de la pastille qui coulisse derrière eux. L'item actif reçoit la classe active (couleur #fff) ; les inactifs restent en --text-secondary. Le script initialise la position sur le premier item au chargement avec i.length > 0 && l(i[0]).

Accessibilité

  • prefers-reduced-motion absent dans le code : aucune vérification n'est faite. Ajoutez @media (prefers-reduced-motion: reduce) { .pill-indicator { transition: none } } dans votre feuille de style pour les utilisateurs sensibles au mouvement.
  • Les .pill-link sont des <span>, non focusables au clavier par défaut. Pour l'accessibilité complète, ajoutez role="tab", tabindex="0" et un gestionnaire keydown (Entrée/Espace) sur chaque item.
  • Le .pill-nav ne porte pas de role="tablist" natif dans le code — à ajouter si l'indicateur pilote un contenu de panneau avec aria-selected et aria-controls.
  • Contraste : le texte actif (blanc #fff) sur fond pastille (#6366f1) atteint ~4,5:1 — limite WCAG AA pour le texte normal. Le texte inactif (#a1a1aa sur #12121a) dépasse 7:1 — niveau AAA.
  • Aucun aria-label n'est posé sur le conteneur nav dans le code de base : à compléter selon votre usage (aria-label="Navigation principale").

Compatibilité navigateur

Utilise getBoundingClientRect, addEventListener et transitions CSS — disponibles dans tous les navigateurs modernes depuis 2019. Zéro dépendance externe.

Chrome 88+✓ Complet
Firefox 78+✓ Complet
Safari 13+✓ Complet
Edge 88+✓ Complet
Mobile iOS✓ Touch OK
Android Chrome✓ Complet

Si <code>getElementById('pillNav')</code> ne trouve aucun élément, le bloc <code>if (e && n)</code> empêche toute erreur JS fatale ; les items restent cliquables mais sans indicateur animé.

Le code

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

index.html — structure
<div class="pill-nav" id="pillNav">
  <div class="pill-indicator" id="pillIndicator"></div>
  <span class="pill-link active" data-index="0">Accueil</span>
  <span class="pill-link" data-index="1">À propos</span>
  <span class="pill-link" data-index="2">Travaux</span>
</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
background (.pill-indicator) #6366f1 Couleur de fond de la pastille — la valeur est codée en dur dans le CSS, remplacez-la directement par votre teinte brand.
--bg-card #12121a Fond du conteneur .pill-nav.
--radius-full 9999px Arrondi de la pastille et du conteneur. 6px donne un look onglet rectangulaire arrondi.
--text-secondary #a1a1aa Couleur du texte des items non sélectionnés.
transition (.pill-indicator) .3s cubic-bezier(.175,.885,.32,1.275) Durée et easing du glissement. Utilisez none pour supprimer toute animation, ease-out pour un glissement sans rebond.
padding (.pill-link) 0.5rem 1.5rem Espacement interne de chaque item. Réduisez à 0.4rem 1rem pour un nav compact.
supplémentaire 3 items Ajoutez autant de spans que nécessaire — getBoundingClientRect recalcule la position exacte à chaque clic, sans index codé en dur.

FAQ

Oui. Le script mesure la position de chaque item au clic via getBoundingClientRect — aucun index n'est codé en dur. Ajoutez ou retirez des <span class="pill-link"> librement : l'indicateur suit automatiquement.
La ligne i.length > 0 && l(i[0]) initialise sur le premier item. Remplacez i[0] par l'index voulu (ex. i[2]) ou par un e.querySelector('.pill-link.active') pour lire l'état défini en HTML.
Par défaut, le JS utilise getElementById('pillNav') — un seul élément par page. Pour plusieurs instances, donnez des ids distincts et dupliquez le bloc de logique pour chaque paire nav/indicateur, ou itérez sur document.querySelectorAll('.pill-nav') après avoir référencé l'indicateur par relation DOM (nav.querySelector('.pill-indicator')).