Modale
La modale ouvre une fenêtre par-dessus la page et bloque l’arrière-plan pour obtenir une confirmation, une saisie ou une information importante. Elle se ferme par un bouton, la touche Échap ou un clic sur le fond.
Exemple de base#
Un bouton avec data-bs-toggle="modal" et data-bs-target ouvre la modale. Le bouton de fermeture porte data-bs-dismiss="modal".
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modale-simple">Voir les conditions</button>
<div class="modal fade" id="modale-simple" tabindex="-1" aria-labelledby="modale-simple-titre" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5" id="modale-simple-titre">Conditions du compte épargne</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">
<p>Le compte épargne est rémunéré à 3,5 % par an. Le dépôt minimum à l'ouverture est de 10 000 FCFA.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Fermer</button>
<button type="button" class="btn btn-primary">Ouvrir un compte</button>
</div>
</div>
</div>
</div>Fond statique#
Avec data-bs-backdrop="static", un clic sur le fond ne ferme plus la modale ; elle « vibre » légèrement. Ajoutez data-bs-keyboard="false" pour désactiver aussi Échap. Réservez ce mode aux étapes qui ne doivent pas être abandonnées par erreur.
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modale-statique">Confirmer un virement</button>
<div class="modal fade" id="modale-statique" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="modale-statique-titre" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5" id="modale-statique-titre">Confirmer le virement</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">
<p>Vous allez virer 250 000 FCFA vers le compte de M. Koné. Cette action est définitive.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Annuler</button>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal">Confirmer</button>
</div>
</div>
</div>
</div>Contenu long et défilement#
Quand le contenu dépasse la fenêtre, toute la page défile avec la modale. Avec .modal-dialog-scrollable, seul le corps défile : l’en-tête et le pied restent visibles.
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modale-longue">Lire le contrat</button>
<div class="modal fade" id="modale-longue" tabindex="-1" aria-labelledby="modale-longue-titre" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5" id="modale-longue-titre">Contrat de prêt personnel</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">
<p>Article 1. Le prêt est accordé pour une durée de 36 mois, remboursable par mensualités constantes.</p>
<p>Article 2. Le taux d'intérêt est fixe pendant toute la durée du prêt.</p>
<p>Article 3. Le remboursement anticipé, total ou partiel, est possible à tout moment, sur demande écrite en agence.</p>
<p>Article 4. En cas d'impayé, la banque informe l'emprunteur par courrier et par SMS avant toute démarche.</p>
<p>Article 5. L'assurance décès-invalidité est obligatoire pour tout prêt supérieur à 1 000 000 FCFA.</p>
<p>Article 6. Le présent contrat est soumis au droit applicable en Côte d'Ivoire.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Fermer</button>
</div>
</div>
</div>
</div>Centrer verticalement#
.modal-dialog-centered place la fenêtre au milieu de l’écran. Il se combine avec .modal-dialog-scrollable.
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modale-centree">Supprimer un bénéficiaire</button>
<div class="modal fade" id="modale-centree" tabindex="-1" aria-labelledby="modale-centree-titre" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5" id="modale-centree-titre">Supprimer ce bénéficiaire ?</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">
<p>Mme Traoré sera retirée de votre liste. Vous pourrez la rajouter plus tard.</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Garder</button>
<button type="button" class="btn btn-danger" data-bs-dismiss="modal">Supprimer</button>
</div>
</div>
</div>
</div>Tailles#
Trois classes modifient la largeur : .modal-sm (300 px), .modal-lg (800 px) et .modal-xl (1140 px). Sans classe, la largeur est de 500 px. Sur petit écran, la modale occupe la largeur disponible.
<div class="d-flex flex-wrap gap-2">
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#modale-petite">Petite</button>
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#modale-large">Large</button>
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#modale-tres-large">Très large</button>
</div>
<div class="modal fade" id="modale-petite" tabindex="-1" aria-labelledby="modale-petite-titre">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5" id="modale-petite-titre">Code reçu</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">Un code a été envoyé par SMS.</div>
</div>
</div>
</div>
<div class="modal fade" id="modale-large" tabindex="-1" aria-labelledby="modale-large-titre">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5" id="modale-large-titre">Tableau d'amortissement</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">Mensualité de 87 500 FCFA sur 24 mois.</div>
</div>
</div>
</div>
<div class="modal fade" id="modale-tres-large" tabindex="-1" aria-labelledby="modale-tres-large-titre">
<div class="modal-dialog modal-xl">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5" id="modale-tres-large-titre">Comparatif des offres</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">Comparez les offres de crédit côte à côte.</div>
</div>
</div>
</div>Plein écran#
.modal-fullscreen prend tout l’écran. Les variantes .modal-fullscreen-{sm|md|lg|xl|xxl}-down ne l’appliquent qu’en dessous du point de rupture : la modale reste une fenêtre sur grand écran.
<div class="d-flex flex-wrap gap-2">
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#modale-plein-ecran">Toujours plein écran</button>
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#modale-plein-md">Plein écran sous md</button>
</div>
<div class="modal fade" id="modale-plein-ecran" tabindex="-1" aria-labelledby="modale-plein-ecran-titre">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5" id="modale-plein-ecran-titre">Relevé de compte</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">Solde au 31 octobre : 1 250 000 FCFA.</div>
</div>
</div>
</div>
<div class="modal fade" id="modale-plein-md" tabindex="-1" aria-labelledby="modale-plein-md-titre">
<div class="modal-dialog modal-fullscreen-md-down">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5" id="modale-plein-md-titre">Choix de l'agence</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">Sélectionnez l'agence où retirer votre carte.</div>
</div>
</div>
</div>Une même modale, plusieurs contenus#
Les événements donnent accès au bouton qui a déclenché l’ouverture (relatedTarget). Lisez-y des attributs data-bs-* pour adapter le contenu avant l’affichage.
<div class="d-flex flex-wrap gap-2">
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#modale-variable" data-bs-compte="Compte courant">Compte courant</button>
<button type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#modale-variable" data-bs-compte="Compte épargne">Compte épargne</button>
</div>
<div class="modal fade" id="modale-variable" tabindex="-1" aria-labelledby="modale-variable-titre">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title fs-5" id="modale-variable-titre">Détail du compte</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">
<p class="mb-0">Compte sélectionné : <strong id="modale-variable-compte">aucun</strong></p>
</div>
</div>
</div>
</div>Script de la modale à contenu variable#
Cet écouteur complète l’exemple précédent.
const modale = document.getElementById('modale-variable');
modale.addEventListener('show.bs.modal', (evenement) => {
const declencheur = evenement.relatedTarget;
const compte = declencheur.getAttribute('data-bs-compte');
modale.querySelector('#modale-variable-compte').textContent = compte;
});Utilisation en JavaScript#
Créez une instance pour ouvrir ou fermer la modale depuis votre code, par exemple après un envoi de formulaire.
const modale = new bootstrap.Modal('#modale-simple', {
backdrop: 'static',
keyboard: false,
});
modale.show();
document.getElementById('modale-simple').addEventListener('hidden.bs.modal', () => {
document.getElementById('bouton-ouverture').focus();
});
// Plus tard
modale.hide();Options
Les options se passent au constructeur ou par attribut (data-bs-backdrop, data-bs-keyboard, data-bs-focus) sur la modale.
| Option | Type | Défaut | Description |
|---|---|---|---|
backdrop | boolean | 'static' | true | Affiche le fond sombre. true : un clic sur le fond ferme la modale ; 'static' : le fond est affiché mais ne ferme pas ; false : pas de fond. |
focus | boolean | true | Place le focus sur la modale à l’ouverture. |
keyboard | boolean | true | Ferme la modale avec la touche Échap. |
Méthodes
| Méthode | Description |
|---|---|
toggle() | Ouvre ou ferme la modale. |
show() | Ouvre la modale. |
hide() | Ferme la modale. |
handleUpdate() | Recalcule la position si le contenu change de hauteur pendant l’affichage (barre de défilement). |
dispose() | Détruit l’instance. |
bootstrap.Modal.getInstance(element) | Renvoie l’instance liée à l’élément, ou null. |
bootstrap.Modal.getOrCreateInstance(element, options) | Renvoie l’instance, ou la crée. |
Événements
Les événements sont émis sur l’élément .modal. Ceux qui précèdent une action (show, hide) sont annulables avec preventDefault().
| Événement | Déclenché quand |
|---|---|
show.bs.modal | L’ouverture est demandée. relatedTarget contient le bouton déclencheur. |
shown.bs.modal | La modale est visible, transition terminée. |
hide.bs.modal | La fermeture est demandée. |
hidden.bs.modal | La modale est fermée, transition terminée. |
hidePrevented.bs.modal | La fermeture a été bloquée (fond statique, clavier désactivé ou preventDefault() sur hide). |
Attributs data-bs-*
| Attribut | Élément | Effet |
|---|---|---|
data-bs-toggle="modal" | Bouton ou lien | Ouvre la modale ciblée. |
data-bs-target="#id" | Bouton | Sélecteur de la modale (pour un lien, href="#id" suffit). |
data-bs-dismiss="modal" | Bouton dans la modale | Ferme la modale. |
data-bs-backdrop | Modale | Option backdrop (true, false ou static). |
data-bs-keyboard | Modale | Option keyboard. |
data-bs-focus | Modale | Option focus. |
Variables Sass
| Variable | Valeur par défaut |
|---|---|
$modal-inner-padding | $spacer (1 rem) |
$modal-footer-margin-between | .5rem |
$modal-dialog-margin | .5rem |
$modal-dialog-margin-y-sm-up | 1.75rem |
$modal-content-bg | var(--bs-body-bg) |
$modal-content-border-color | var(--bs-border-color-translucent) |
$modal-content-border-radius | var(--bs-border-radius-lg) |
$modal-backdrop-bg | $black |
$modal-backdrop-opacity | .5 |
$modal-header-border-color | var(--bs-border-color) |
$modal-sm | 300px |
$modal-md | 500px |
$modal-lg | 800px |
$modal-xl | 1140px |
$modal-fade-transform | translate(0, -50px) |
$modal-transition | transform .3s ease-out |
Personnalisation#
Les variables CSS --bs-modal-* s’appliquent à la classe .modal : ajoutez votre propre classe pour modifier une seule modale.
// Sass : fenêtre plus large et fond plus sombre
$modal-md: 600px;
$modal-backdrop-opacity: 0.65;
// CSS : une modale précise
.modale-confirmation {
--bs-modal-width: 420px;
--bs-modal-border-radius: 1rem;
--bs-modal-header-border-width: 0;
--bs-modal-footer-border-width: 0;
}Bonnes pratiques
À faire
- Donnez un titre clair à chaque modale et reliez-le avec
aria-labelledby. - Proposez toujours une sortie évidente : bouton de fermeture, bouton « Annuler » et touche Échap.
- Libellez les boutons d’action par un verbe précis (« Confirmer le virement », « Supprimer »), pas « OK ».
- Renvoyez le focus au bouton déclencheur après la fermeture si vous ouvrez la modale en JavaScript.
À éviter
- N’empilez pas plusieurs modales : une seule doit être ouverte à la fois.
- N’utilisez pas une modale pour un message qui peut rester dans la page : préférez une alerte ou un toast.
- Ne mettez pas de formulaires très longs dans une modale : une page dédiée est plus adaptée.
- Ne désactivez pas la fermeture (fond statique et clavier) sans offrir un bouton visible pour sortir.
Accessibilité
- Cauri ajoute
role="dialog"etaria-modal="true"à l’ouverture, et retirearia-hidden; les deux attributs repassent à leur état initial à la fermeture. - Le focus est piégé dans la modale : Tab et Maj+Tab restent à l’intérieur jusqu’à la fermeture, puis le focus revient au déclencheur.
- La touche Échap ferme la modale, sauf si
keyboardvautfalse. - Placez
tabindex="-1"sur.modalet mettez le titre dans un élément de titre (h2) relié pararia-labelledby. - Pour un texte long, ajoutez
aria-describedbyvers le paragraphe qui résume l’enjeu.