Éléments interactifs
Popup, Tooltip, Accordion, Tabs et Slider. Tous les éléments sont emboîtables (nestable) et initialisés automatiquement au chargement.
Popup / Modal
Système de popup/modal avec overlay, fermeture par clic extérieur, touche Escape et bouton. Les popups sont empilables (nestable).
Titre du popup
Contenu du popup centré. Cliquez en dehors, sur × ou Escape pour fermer.
Structure HTML
<button data-popup-target="demo">Ouvrir le popup</button>
<div class="popup" data-popup="demo">
<div class="popup__overlay"></div>
<div class="popup__content">
<button class="popup__close" data-popup-close>×</button>
<h2>Titre du popup</h2>
<p>Contenu du popup.</p>
</div>
</div>
Attributs
| Attribut | Rôle |
|---|---|
data-popup-target="id" | Bouton qui ouvre le popup correspondant |
data-popup="id" | Identifiant du popup |
data-popup-close | Bouton de fermeture (dans le popup) |
Fermeture
- Clic sur
.popup__overlay - Clic sur
[data-popup-close] - Touche
Escape(ferme le dernier ouvert)
Popups imbriqués
Les popups peuvent être imbriqués. Le z-index est géré automatiquement par CSS (.popup .popup → z-index supérieur). La touche Escape ferme toujours le dernier popup ouvert.
Variantes de position
Panneau droit
Panneau latéral glissant depuis la droite.
Panneau gauche
Panneau latéral glissant depuis la gauche.
Bottom sheet
Panneau glissant depuis le bas.
Panneau haut
Panneau glissant depuis le haut.
Ajoutez data-popup-position sur le .popup pour changer l'animation et la disposition :
| Valeur | Comportement |
|---|---|
| (aucune) | Centré (défaut) — animation scale + fade |
right | Panneau latéral droit — pleine hauteur, max 480px, glisse depuis la droite |
left | Panneau latéral gauche — pleine hauteur, max 480px, glisse depuis la gauche |
bottom | Bottom sheet — pleine largeur, max 80vh, glisse depuis le bas |
top | Panneau supérieur — pleine largeur, max 80vh, glisse depuis le haut |
Popup centré (défaut)
<button data-popup-target="demo">Ouvrir</button>
<div class="popup" data-popup="demo">
<div class="popup__overlay"></div>
<div class="popup__content">
<button class="popup__close" data-popup-close>×</button>
<h2>Titre</h2>
<p>Contenu du popup.</p>
</div>
</div>
Panneau droit
<button data-popup-target="menu">Menu</button>
<div class="popup" data-popup="menu" data-popup-position="right">
<div class="popup__overlay"></div>
<div class="popup__content">
<button class="popup__close" data-popup-close>×</button>
<h2>Menu</h2>
</div>
</div>
Panneau gauche
<button data-popup-target="sidebar">Sidebar</button>
<div class="popup" data-popup="sidebar" data-popup-position="left">
<div class="popup__overlay"></div>
<div class="popup__content">
<button class="popup__close" data-popup-close>×</button>
<h2>Sidebar</h2>
</div>
</div>
Bottom sheet
<button data-popup-target="sheet">Bottom sheet</button>
<div class="popup" data-popup="sheet" data-popup-position="bottom">
<div class="popup__overlay"></div>
<div class="popup__content">
<button class="popup__close" data-popup-close>×</button>
<p>Contenu en bas.</p>
</div>
</div>
Panneau haut
<button data-popup-target="top-panel">Panneau haut</button>
<div class="popup" data-popup="top-panel" data-popup-position="top">
<div class="popup__overlay"></div>
<div class="popup__content">
<button class="popup__close" data-popup-close>×</button>
<p>Contenu en haut.</p>
</div>
</div>
Sur mobile (≤ 600px), les panneaux latéraux passent en pleine largeur automatiquement.
Classes CSS
| Classe | Description |
|---|---|
.popup | Conteneur principal (caché par défaut) |
.popup--active | Popup visible (ajouté par JS) |
.popup__overlay | Fond semi-transparent |
.popup__content | Boîte de contenu (animation scale + fade) |
.popup__close | Bouton de fermeture (positionné en haut à droite) |
Attributs récapitulatifs
| Attribut | Rôle |
|---|---|
data-popup-target="id" | Bouton qui ouvre le popup correspondant |
data-popup="id" | Identifiant du popup |
data-popup-close | Bouton de fermeture (dans le popup) |
data-popup-position="right|left|bottom|top" | Variante de position (optionnel) |
Tooltip
Bulle d'information au survol ou au focus. Repositionnement automatique si la bulle déborde de la fenêtre.
Utilisation
<span data-tooltip="Texte de la bulle">Survolez-moi</span>
<!-- Avec position -->
<span data-tooltip="Info" data-tooltip-position="bottom">En bas</span>
<span data-tooltip="Info" data-tooltip-position="left">À gauche</span>
<span data-tooltip="Info" data-tooltip-position="right">À droite</span>
Attributs
| Attribut | Description |
|---|---|
data-tooltip="texte" | Texte de la bulle |
data-tooltip-position | Position : top (défaut), bottom, left, right |
Repositionnement automatique
Si la bulle déborde du viewport, elle se repositionne automatiquement (ex. top → bottom si pas de place en haut).
Classes CSS
| Classe | Description |
|---|---|
.tooltip | Ajoutée automatiquement à l'élément parent |
.tooltip__bubble | Bulle de texte (créée dynamiquement) |
.tooltip__bubble--top/bottom/left/right | Variantes de position |
.tooltip__bubble--visible | Bulle visible (avec transition) |
Accordion
Panneaux dépliables avec animation CSS Grid. Support du mode multiple et de l'imbrication.
Structure HTML
<div class="accordion">
<div class="accordion__item">
<button class="accordion__header">Section 1</button>
<div class="accordion__body">
<div>Contenu du panneau 1.</div>
</div>
</div>
<div class="accordion__item">
<button class="accordion__header">Section 2</button>
<div class="accordion__body">
<div>Contenu du panneau 2.</div>
</div>
</div>
</div>
Mode multiple
Par défaut, un seul panneau est ouvert à la fois. Ajoutez data-accordion-multiple pour permettre l'ouverture de plusieurs panneaux simultanément :
<div class="accordion" data-accordion-multiple>
...
</div>
Accordéon imbriqué
Les accordéons peuvent être imbriqués. Chaque niveau gère ses propres items indépendamment :
<div class="accordion">
<div class="accordion__item">
<button class="accordion__header">Parent</button>
<div class="accordion__body">
<div>
<div class="accordion">
<div class="accordion__item">
<button class="accordion__header">Enfant</button>
<div class="accordion__body">
<div>Contenu imbriqué.</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Classes CSS
| Classe | Description |
|---|---|
.accordion | Conteneur principal (bordure + arrondi) |
.accordion__item | Un panneau individuel |
.accordion__item--active | Panneau ouvert (ajouté par JS) |
.accordion__header | En-tête cliquable (bouton) |
.accordion__body | Contenu (animation via grid-template-rows) |
Tabs
Système d'onglets avec navigation et panneaux. Support de l'imbrication.
Contenu du premier onglet.
Contenu du deuxième onglet.
Contenu du troisième onglet avec tabs imbriqués :
Contenu imbriqué A.
Contenu imbriqué B.
Structure HTML
<div class="tabs">
<div class="tabs__nav">
<button class="tabs__tab" data-tab="tab1">Onglet 1</button>
<button class="tabs__tab" data-tab="tab2">Onglet 2</button>
<button class="tabs__tab" data-tab="tab3">Onglet 3</button>
</div>
<div class="tabs__panel" data-tab-panel="tab1">Contenu 1</div>
<div class="tabs__panel" data-tab-panel="tab2">Contenu 2</div>
<div class="tabs__panel" data-tab-panel="tab3">Contenu 3</div>
</div>
Onglet actif par défaut
Par défaut, le premier onglet est actif. Ajoutez data-tab-active pour choisir un autre :
<button class="tabs__tab" data-tab="tab2" data-tab-active>Onglet 2</button>
Attributs
| Attribut | Description |
|---|---|
data-tab="id" | Identifiant de l'onglet (sur le bouton) |
data-tab-panel="id" | Identifiant du panneau associé |
data-tab-active | Onglet actif au chargement (optionnel) |
Classes CSS
| Classe | Description |
|---|---|
.tabs | Conteneur principal |
.tabs__nav | Barre de navigation (scrollable horizontalement) |
.tabs__tab | Bouton d'onglet |
.tabs__tab--active | Onglet actif (souligné en couleur primaire) |
.tabs__panel | Panneau de contenu (caché par défaut) |
.tabs__panel--active | Panneau visible |
Slider / Carousel
Carousel avec navigation par boutons, dots, swipe tactile, drag souris, autoplay et boucle. Support multi-slides.
Structure HTML
<div class="slider" data-slider-per-view="1">
<div class="slider__track">
<div class="slider__slide">Slide 1</div>
<div class="slider__slide">Slide 2</div>
<div class="slider__slide">Slide 3</div>
</div>
<button class="slider__prev"></button>
<button class="slider__next"></button>
<div class="slider__dots"></div>
</div>
Attributs
| Attribut | Valeur | Description |
|---|---|---|
data-slider-per-view | 1, 2, 3, 4 | Nombre de slides visibles (défaut : 1) |
data-slider-loop | true | Boucle infinie |
data-slider-autoplay | 3000 | Défilement auto en ms (pause au survol) |
data-slider-draggable | true | Drag à la souris (en plus du swipe tactile) |
data-slider-gap | xs | sm | md | lg | xl | Espacement entre les slides |
data-slider-dots | false | Masquer les dots de navigation |
data-slider-arrows | false | Masquer les flèches de navigation |
Personnalisation des flèches
Les flèches utilisent par défaut les icônes chevron. Personnalisez-les via ces attributs sur le .slider :
| Attribut | Valeur | Description |
|---|---|---|
data-slider-arrow-prev | Nom d'icône | Icône du bouton précédent (ex: arrow-left) |
data-slider-arrow-next | Nom d'icône | Icône du bouton suivant (ex: arrow-right) |
data-slider-arrow-type | outline | solid | Type d'icône (défaut : outline) |
data-slider-arrow-icon-size | Nombre en px | Taille de l'icône SVG (défaut : 20) |
data-slider-arrow-size | Nombre en px | Taille du bouton (défaut : 40) |
data-slider-arrow-color | Couleur CSS | Couleur de l'icône |
data-slider-arrow-hover-color | Couleur CSS | Couleur de l'icône au survol |
data-slider-arrow-bg | Couleur CSS | Fond du bouton |
data-slider-arrow-hover-bg | Couleur CSS | Fond du bouton au survol |
<div class="slider"
data-slider-arrow-prev="arrow-left"
data-slider-arrow-next="arrow-right"
data-slider-arrow-color="#fff"
data-slider-arrow-bg="var(--color-primary)"
data-slider-arrow-hover-bg="#1d4ed8">
...
</div>
Les icônes sont chargées depuis le système d'icônes (icons.js). Les styles peuvent aussi être définis via les CSS custom properties --slider-arrow-* directement en CSS.
CSS custom properties
| Variable | Description |
|---|---|
--slider-arrow-size | Taille du bouton |
--slider-arrow-color | Couleur de l'icône |
--slider-arrow-hover-color | Couleur au survol |
--slider-arrow-bg | Fond du bouton |
--slider-arrow-hover-bg | Fond au survol |
--slider-arrow-border | Couleur de bordure |
Navigation
- Boutons :
.slider__prevet.slider__next(optionnels) - Dots :
.slider__dots(générés automatiquement par JS, optionnel) - Swipe : tactile natif (seuil 50px)
- Drag souris : activé via
data-slider-draggable="true"
Exemple complet
<div class="slider"
data-slider-per-view="2"
data-slider-loop="true"
data-slider-autoplay="4000"
data-slider-draggable="true"
data-slider-gap="md"
data-slider-arrow-prev="arrow-left"
data-slider-arrow-next="arrow-right"
data-slider-arrow-color="#fff"
data-slider-arrow-bg="var(--color-primary)">
<div class="slider__track">
<div class="slider__slide"><img src="img/1.jpg" alt=""></div>
<div class="slider__slide"><img src="img/2.jpg" alt=""></div>
<div class="slider__slide"><img src="img/3.jpg" alt=""></div>
<div class="slider__slide"><img src="img/4.jpg" alt=""></div>
</div>
<button class="slider__prev"></button>
<button class="slider__next"></button>
<div class="slider__dots"></div>
</div>
Classes CSS
| Classe | Description |
|---|---|
.slider | Conteneur principal (overflow: hidden) |
.slider__track | Piste flex (translateX pour la navigation) |
.slider__slide | Un slide individuel |
.slider__prev, .slider__next | Boutons flèches (positionnés en absolu) |
.slider__dots | Conteneur des points de navigation |
.slider__dot | Point individuel (créé par JS) |
.slider__dot--active | Point actif |
API JavaScript
| Fonction | Description |
|---|---|
initElements(root) | Initialise tous les éléments dans root (défaut : document). Appelé auto au DOMContentLoaded. |
Appelez initElements(el) manuellement après avoir injecté du HTML dynamique contenant des éléments interactifs.
Inclure dans une page
<link rel="stylesheet" href="core/css/elements.css">
<script src="core/js/elements.js" defer></script>