5.4 — Modal & offcanvas
⏱️ TL;DR — Une modal (
.modal) est une fenêtre par-dessus la page, ouverte pardata-bs-toggle="modal"+data-bs-target. Un offcanvas (.offcanvas) est un panneau qui glisse depuis un bord (offcanvas-start/end/top/bottom). Les deux posent un backdrop et piègent le focus — c’est du JS Bootstrap.
🎯 Objectifs
- Ouvrir et structurer une modale.
- Régler taille, scroll et centrage.
- Créer un panneau offcanvas (menu mobile, panier…).
Modal
<!-- déclencheur -->
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#maModale">Ouvrir</button>
<!-- la modale -->
<div class="modal fade" id="maModale" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Titre</h5>
<button class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">Contenu de la modale.</div>
<div class="modal-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
<button class="btn btn-primary">Enregistrer</button>
</div>
</div>
</div>
</div>Options de dialog :
- Tailles :
modal-sm,modal-lg,modal-xl,modal-fullscreen. - Centrée :
modal-dialog-centered. - Corps défilant :
modal-dialog-scrollable.
Piloter en JS
const modal = new bootstrap.Modal('#maModale')
modal.show()
modal.hide()
document.getElementById('maModale').addEventListener('hidden.bs.modal', () => {/* … */})Offcanvas
<button class="btn btn-primary" data-bs-toggle="offcanvas" data-bs-target="#menu">Menu</button>
<div class="offcanvas offcanvas-start" id="menu" tabindex="-1">
<div class="offcanvas-header">
<h5 class="offcanvas-title">Navigation</h5>
<button class="btn-close" data-bs-dismiss="offcanvas" aria-label="Fermer"></button>
</div>
<div class="offcanvas-body">
<ul class="navbar-nav">…</ul>
</div>
</div>Bords : offcanvas-start (gauche), -end (droite), -top, -bottom. Option data-bs-backdrop, data-bs-scroll.
Navbar → offcanvas responsive (5.x)
navbar-expand-lg combiné à un offcanvas permet un menu classique sur desktop et un panneau glissant sur mobile — motif courant pour les menus mobiles.
⚠️ Piège — Deux pièges d’accessibilité : (1) toujours un
aria-labelsur lebtn-close; (2) laisser Bootstrap gérer le focus trap — n’ajoutez pasaria-hiddenen dur pendant que la modale est ouverte. Aussi : évitez d’imbriquer une modale dans une autre.
💡 Pour un dev React — Le duo backdrop + focus trap + verrouillage du scroll est délicat à réimplémenter. En React,
<Modal>et<Offcanvas>dereact-bootstrapgèrent l’ouverture par une propshowet unonHide, ce qui s’intègre naturellement à l’état. Fortement recommandé plutôt que le JS natif.
✏️ Exercices
- Une modale de confirmation centrée verticalement, taille small.
✅ Solution
<div class="modal-dialog modal-dialog-centered modal-sm">…</div>.
- Un panneau panier qui glisse depuis la droite.
✅ Solution
<div class="offcanvas offcanvas-end" id="panier">…</div> + un déclencheur data-bs-toggle="offcanvas" data-bs-target="#panier".
🧠 Quiz de révision
1. Quel attribut ouvre une modale ?
data-bs-toggle="modal" (+ data-bs-target).
2. Comment centrer une modale verticalement ?
modal-dialog-centered.
3. Depuis quels bords un offcanvas peut-il glisser ?
start, end, top, bottom.
4. Quel événement JS se déclenche après fermeture d’une modale ?
hidden.bs.modal.
5. Que fait Bootstrap pour l’accessibilité d’une modale ouverte ?
Il piège le focus (focus trap) et pose un backdrop.
Chapitre suivant : 5.5 — Toasts, tooltips, popovers