Tab Slider
Rail d'onglets avec indicateur glissant — positionné par getBoundingClientRect, animé par transition cubic-bezier, adapté à toute largeur d'onglet.
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



Comment ça marche
Au clic sur un <span class="tab-slider-item">, la fonction mesure le rectangle exact du <span> via getBoundingClientRect() et soustrait le rectangle du conteneur parent pour obtenir un décalage left relatif en pixels. Elle applique simultanément indicator.style.width et indicator.style.left : l'indicateur adopte la largeur et la position précises de l'onglet cliqué, quelle que soit la longueur de chaque label.
La transition CSS 0,35 s cubic-bezier(0,4, 0, 0,2, 1) (courbe Material Design standard-ease) est posée sur le <div> indicateur. Comme width et left changent simultanément, l'indicateur se rétrécie ou s'élargit en route quand les onglets ont des largeurs différentes — produisant un glissement naturel plutôt qu'une simple translation rigide.
L'indicateur est positionné en position: absolute dans le rail, ancré à top: 6px et height: calc(100% - 12px) pour un inset de 6 px. Il porte un background: linear-gradient(135deg, #6366f1 → #8b5cf6) et un box-shadow indigo pour le halo. Les <span> onglets se trouvent devant lui grâce à z-index: 1.
Il n'y a pas de gestion de prefers-reduced-motion dans le code livré : la transition tourne toujours. Pour les utilisateurs sensibles au mouvement, ajoutez @media (prefers-reduced-motion: reduce) { .tab-slider-indicator { transition: none } }.
Accessibilité
- Pas de prefers-reduced-motion : la transition de l'indicateur s'exécute toujours. Ajoutez manuellement
@media (prefers-reduced-motion: reduce) { .tab-slider-indicator { transition: none } }pour la désactiver. - Les onglets sont des
<span>, non focusables au clavier par défaut. Pour la navigation clavier, convertissez-les en<button>ou ajouteztabindex="0"avec un gestionnairekeydownsur Enter et Space. - Aucun rôle ARIA n'est déclaré : le conteneur n'est pas annoncé
tablist, les items ne portent nirole="tab"niaria-selected. Le patron WAI-ARIA Tabs complet nécessite ces attributs. - Contraste de l'onglet actif (blanc sur indigo
#6366f1) : ratio ≈ 4,1:1 — en-dessous du seuil WCAG AA 4,5:1 pour le texte normal. Passez à un indigo plus foncé ou à une taille de police ≥ 18 px pour atteindre AA. - Contraste de l'onglet inactif (
#a1a1aasur#12121a) : ratio ≈ 7,6:1 — WCAG AA et AAA validés.
Compatibilité navigateur
Nécessite uniquement getBoundingClientRect, classList et querySelectorAll — APIs DOM disponibles dans tous les navigateurs modernes et dans IE11.
Sans JavaScript, l'indicateur reste à sa position initiale (définie par l'attribut <code>style</code> inline) et les onglets s'affichent sans interaction — aucune erreur fatale, la mise en page reste lisible.
Le code
Structure HTML à coller dans votre page (CSS + JS disponibles avec un compte premium) :
<div class="tab-slider-container" id="tabSlider">
<div class="tab-slider-indicator" id="tabSliderIndicator"></div>
<span class="tab-slider-item active" data-index="0">Onglet 1</span>
<span class="tab-slider-item" data-index="1">Onglet 2</span>
<span class="tab-slider-item" data-index="2">Onglet 3</span>
</div>
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éfaut | Effet |
|---|---|---|
| --bg-card | #12121a | Couleur de fond du rail. Passez à transparent ou à une couleur brand pour intégrer le composant sur n'importe quel fond. |
| --border | rgba(255,255,255,0.08) | Couleur et opacité de la bordure du conteneur. Augmentez l'opacité pour un contour plus visible ; transparent pour le supprimer. |
| --radius-lg | 0.75rem | Arrondi du rail. 100px = look pill ; 0 = angles droits. |
| --radius-md | 0.5rem | Arrondi de l'indicateur. Gardez-le légèrement inférieur à --radius-lg pour conserver le visuel d'inset. |
| --text-secondary | #a1a1aa | Couleur des onglets inactifs. #64748b convient à un fond clair ; #6b7280 à un fond intermédiaire. |
| Gradient indicateur | linear-gradient(135deg, #6366f1 0, #8b5cf6 100%) | Modifiez les deux couleurs hex dans .tab-slider-indicator { background: … } pour adapter la teinte brand. Le box-shadow adjacent porte la même valeur indigo. |
| Transition indicateur | .35s cubic-bezier(.4,0,.2,1) | Dans .tab-slider-indicator { transition: … } : réduisez à .2s ease pour plus de réactivité, ou 0s pour désactiver l'animation (mode réduit-motion). |
FAQ
<div> indicateur, des <span> onglets et une quinzaine de lignes de JS. Aucune dépendance npm, aucun CSS framework. Intégrable tel quel dans Angular, React ou Vue en encapsulant le HTML dans un composant et en appelant l'initialisation après le montage.<span class="tab-slider-item"> dans le conteneur. L'appel initial r(o[0]) place automatiquement l'indicateur sur le premier onglet au chargement. Aucun index à configurer — la largeur de chaque onglet est mesurée à la volée via getBoundingClientRect.getBoundingClientRect ne s'exécute qu'au clic. Sur les layouts fluides où les largeurs d'onglets changent au redimensionnement, ajoutez window.addEventListener('resize', () => r(activeTab)) (avec une référence à l'onglet actif courant) pour recalculer la position de l'indicateur.