Composant de navigation par onglets. Un clic sur un bouton masque le panneau actif et affiche le panneau
cible avec une animation fade in. Le premier onglet actif est déterminé par la classe
.active ou par défaut le premier bouton.
Contenu du panneau 1.
Contenu du panneau 2.
Contenu du panneau 3.
Contenu du panneau 1.
Contenu du panneau 2.
Contenu du panneau 3.
Le data-target de chaque bouton doit correspondre
exactement à l'id du panneau associé. Le JS gère
les deux formats : #id ou
id.
⚠️ Chaque bouton doit posséder un id. Sans
id sur le bouton, le JS en génère un automatiquement
via Math.random() pour assurer le lien
aria-labelledby sur le panneau.
Le JS cherche le premier bouton portant la classe
.active pour l'activer au chargement.
Si aucun bouton ne porte cette classe, c'est le premier bouton de la liste qui est activé par défaut.
| CLASSE / ATTRIBUT | ÉLÉMENT | DESCRIPTION |
|---|---|---|
[data-ui="tab"] |
<div> |
Wrapper principal. Marque la racine du composant pour le JS. |
[data-ui="tab-panel"] |
<div> |
Panneau de contenu. Masqué par défaut via display: none.
Visible lorsqu'il porte la classe .show
(display: block). |
.tab-panel |
<div> |
Style du panneau : bordure, border-radius et paddings via variables CSS. |
.active |
<button> |
Marque le bouton actif. Posée et retirée par le JS à chaque changement d'onglet. Peut être présente au chargement pour définir l'onglet ouvert par défaut. |
| ÉTAT | ÉLÉMENT | DESCRIPTION |
|---|---|---|
| Actif | .active + aria-selected="true" + tabindex="0" |
Bouton de l'onglet actif. Le panneau associé est visible (.show,
hidden retiré). |
| Inactif | aria-selected="false" + tabindex="-1" |
Bouton inactif. Le panneau associé est masqué (hidden
posé, .show retiré). |
| En animation | .anim-fade-in + .anim-200 |
Classes posées temporairement sur le panneau à l'affichage. Retirées automatiquement via
animationend. Non appliquées pour le premier
onglet actif au chargement. |
Le composant est piloté par la classe Tab. Elle s'appuie
sur la délégation d'événements (un seul listener sur
document).
import Tab from './Tab.js';
// Une seule instance suffit pour toute la page.
new Tab();
La classe implémente un guard Tab.initialized :
instancier Tab plusieurs fois n'entraîne aucun
doublon de listeners.
| ATTRIBUT | ÉLÉMENT | DESCRIPTION |
|---|---|---|
data-ui="tab" |
wrapper |
Marque la racine du composant. Le JS s'appuie sur cet attribut pour trouver les boutons et les panneaux associés. |
data-target |
<button> |
Sélecteur du panneau cible. Accepte #id ou
id. |
data-ui="tab-panel" |
panneau |
Marque chaque panneau de contenu. Utilisé par le JS pour réinitialiser tous les panneaux avant d'afficher le panneau cible. |
| MÉTHODE | DESCRIPTION |
|---|---|
Tab.init() |
Initialise tous les composants [data-ui="tab"]
du DOM. Pose les attributs ARIA, masque tous les panneaux, active le premier onglet. |
Tab.resetPanel(content) |
Masque tous les panneaux [data-ui="tab-panel"]
du conteneur : retire .show et pose
hidden. |
Tab.resetButton(nav) |
Désactive tous les boutons du <nav> :
retire .active, pose
aria-selected="false" et
tabindex="-1". |
Tab.show(button, tabPanel, first) |
Active un bouton et affiche son panneau. Si first = true
(chargement initial), aucune animation n'est jouée. Sinon, ajoute
.anim-fade-in et
.anim-200, retirées via
animationend. |
| TOKEN | RÔLE |
|---|---|
--tab-panel-border-color |
Couleur de la bordure du panneau |
--tab-panel-border-style |
Style de la bordure (solid, dashed…) |
--tab-panel-border-width |
Épaisseur de la bordure |
--tab-panel-border-radius |
Rayon des coins du panneau |
--tab-panel-padding-x |
Padding horizontal du panneau |
--tab-panel-padding-y |
Padding vertical du panneau |
| PRATIQUE | DÉTAIL |
|---|---|
role="tablist" |
Posé sur le <nav>. Indique aux lecteurs
d'écran que l'élément contient une liste d'onglets. |
role="tab" |
Posé sur chaque <button>. Identifie
l'élément comme un onglet de navigation. |
role="tabpanel" |
Posé sur chaque panneau. Identifie la zone de contenu associée à un onglet. |
aria-selected |
Mis à jour automatiquement par le JS. true
sur le bouton actif, false sur les autres. |
aria-controls |
Lie chaque bouton à l'id de son panneau.
Initialisé par Tab.init(). |
aria-labelledby |
Lie chaque panneau à l'id de son bouton.
Initialisé par Tab.init(). |
tabindex |
0 sur le bouton actif (accessible via Tab),
-1 sur les autres (exclus du flux Tab natif).
Mis à jour automatiquement par le JS. |
hidden |
Posé sur les panneaux inactifs. Masque le contenu aux technologies d'assistance. |
Toujours ajouter un id sur chaque bouton onglet.
Sans id, le JS en génère un aléatoire — ce qui
peut poser des problèmes de cohérence si le DOM est rechargé dynamiquement.
Utiliser <nav role="tablist"> comme
conteneur des boutons. Le JS s'appuie sur
button.parentElement pour cibler la navigation
et réinitialiser les boutons via Tab.resetButton().
Ne pas imbriquer plusieurs composants [data-ui="tab"]
l'un dans l'autre. Le JS remonte au premier parent
[data-ui="tab"] via
closest() — une imbrication créerait des conflits
dans la détection des panneaux et des boutons.
Ne pas instancier Tab avant le chargement du DOM.
Utilisez DOMContentLoaded ou placez le script
en bas de page.
Tab · WEBDEV-UI DOCS / V1