Aller au contenu
BDU Cauri, accueilv0.1.0
ComposantsJavaScript requis

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.

Options
OptionTypeDéfautDescription
backdropboolean | 'static'trueAffiche 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.
focusbooleantruePlace le focus sur la modale à l’ouverture.
keyboardbooleantrueFerme la modale avec la touche Échap.

Méthodes

Méthodes
MéthodeDescription
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énements
ÉvénementDéclenché quand
show.bs.modalL’ouverture est demandée. relatedTarget contient le bouton déclencheur.
shown.bs.modalLa modale est visible, transition terminée.
hide.bs.modalLa fermeture est demandée.
hidden.bs.modalLa modale est fermée, transition terminée.
hidePrevented.bs.modalLa fermeture a été bloquée (fond statique, clavier désactivé ou preventDefault() sur hide).

Attributs data-bs-*

Attributs data-bs-*
AttributÉlémentEffet
data-bs-toggle="modal"Bouton ou lienOuvre la modale ciblée.
data-bs-target="#id"BoutonSélecteur de la modale (pour un lien, href="#id" suffit).
data-bs-dismiss="modal"Bouton dans la modaleFerme la modale.
data-bs-backdropModaleOption backdrop (true, false ou static).
data-bs-keyboardModaleOption keyboard.
data-bs-focusModaleOption focus.

Variables Sass

Variables Sass
VariableValeur par défaut
$modal-inner-padding$spacer (1 rem)
$modal-footer-margin-between.5rem
$modal-dialog-margin.5rem
$modal-dialog-margin-y-sm-up1.75rem
$modal-content-bgvar(--bs-body-bg)
$modal-content-border-colorvar(--bs-border-color-translucent)
$modal-content-border-radiusvar(--bs-border-radius-lg)
$modal-backdrop-bg$black
$modal-backdrop-opacity.5
$modal-header-border-colorvar(--bs-border-color)
$modal-sm300px
$modal-md500px
$modal-lg800px
$modal-xl1140px
$modal-fade-transformtranslate(0, -50px)
$modal-transitiontransform .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" et aria-modal="true" à l’ouverture, et retire aria-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 keyboard vaut false.
  • Placez tabindex="-1" sur .modal et mettez le titre dans un élément de titre (h2) relié par aria-labelledby.
  • Pour un texte long, ajoutez aria-describedby vers le paragraphe qui résume l’enjeu.
Charte provisoire, déduite du site public de la BDU CI. Elle sera remplacée par la charte officielle.