Aller au contenu
BDU Cauri, accueilv0.1.0
ComposantsJavaScript requis

Offcanvas

L’offcanvas est un panneau qui glisse depuis un bord de l’écran, utile pour un menu mobile, des filtres ou un panier. Il garde la page visible derrière lui et se ferme par un bouton, Échap ou un clic sur le fond.

Exemple de base#

Un bouton data-bs-toggle="offcanvas" ciblant l'id du panneau l’ouvre. Un lien fonctionne aussi, avec href="#id" et role="button". Le panneau se compose d’un en-tête et d’un corps.

Ouvrir avec un lien
Mes comptes

Compte courant : 1 250 000 FCFA

Compte épargne : 3 400 000 FCFA

Mes cartes

Carte Visa Classic se terminant par 4821.

<div class="d-flex flex-wrap gap-2">
  <a class="btn btn-primary" data-bs-toggle="offcanvas" href="#offcanvas-lien" role="button" aria-controls="offcanvas-lien">Ouvrir avec un lien</a>
  <button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-bouton" aria-controls="offcanvas-bouton">Ouvrir avec un bouton</button>
</div>

<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvas-lien" aria-labelledby="offcanvas-lien-titre">
  <div class="offcanvas-header">
    <h2 class="offcanvas-title fs-5" id="offcanvas-lien-titre">Mes comptes</h2>
    <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Fermer"></button>
  </div>
  <div class="offcanvas-body">
    <p>Compte courant : 1 250 000 FCFA</p>
    <p>Compte épargne : 3 400 000 FCFA</p>
  </div>
</div>

<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvas-bouton" aria-labelledby="offcanvas-bouton-titre">
  <div class="offcanvas-header">
    <h2 class="offcanvas-title fs-5" id="offcanvas-bouton-titre">Mes cartes</h2>
    <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Fermer"></button>
  </div>
  <div class="offcanvas-body">
    <p>Carte Visa Classic se terminant par 4821.</p>
    <button type="button" class="btn btn-outline-primary" data-bs-dismiss="offcanvas">Fermer le panneau</button>
  </div>
</div>

Positions#

Choisissez le bord avec .offcanvas-start (gauche), .offcanvas-end (droite), .offcanvas-top (haut) ou .offcanvas-bottom (bas). La largeur des panneaux latéraux est de 400 px, la hauteur des panneaux haut et bas de 30 vh.

Panneau à gauche
Filtrer les opérations par période.
Panneau à droite
Détail de la dernière opération.
Panneau en haut
Information importante sur les horaires d'agence.
Panneau en bas
Raccourcis : virement, paiement de facture, recharge mobile.
<div class="d-flex flex-wrap gap-2">
  <button class="btn btn-outline-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-gauche">Gauche</button>
  <button class="btn btn-outline-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-droite">Droite</button>
  <button class="btn btn-outline-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-haut">Haut</button>
  <button class="btn btn-outline-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-bas">Bas</button>
</div>

<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvas-gauche" aria-labelledby="offcanvas-gauche-titre">
  <div class="offcanvas-header">
    <h2 class="offcanvas-title fs-5" id="offcanvas-gauche-titre">Panneau à gauche</h2>
    <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Fermer"></button>
  </div>
  <div class="offcanvas-body">Filtrer les opérations par période.</div>
</div>
<div class="offcanvas offcanvas-end" tabindex="-1" id="offcanvas-droite" aria-labelledby="offcanvas-droite-titre">
  <div class="offcanvas-header">
    <h2 class="offcanvas-title fs-5" id="offcanvas-droite-titre">Panneau à droite</h2>
    <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Fermer"></button>
  </div>
  <div class="offcanvas-body">Détail de la dernière opération.</div>
</div>
<div class="offcanvas offcanvas-top" tabindex="-1" id="offcanvas-haut" aria-labelledby="offcanvas-haut-titre">
  <div class="offcanvas-header">
    <h2 class="offcanvas-title fs-5" id="offcanvas-haut-titre">Panneau en haut</h2>
    <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Fermer"></button>
  </div>
  <div class="offcanvas-body">Information importante sur les horaires d'agence.</div>
</div>
<div class="offcanvas offcanvas-bottom" tabindex="-1" id="offcanvas-bas" aria-labelledby="offcanvas-bas-titre">
  <div class="offcanvas-header">
    <h2 class="offcanvas-title fs-5" id="offcanvas-bas-titre">Panneau en bas</h2>
    <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Fermer"></button>
  </div>
  <div class="offcanvas-body small">Raccourcis : virement, paiement de facture, recharge mobile.</div>
</div>

Fond et défilement#

Par défaut, le fond est affiché et la page ne défile plus. data-bs-scroll="true" laisse défiler la page ; data-bs-backdrop="false" retire le fond ; data-bs-backdrop="static" empêche la fermeture par clic sur le fond.

Page défilable
Vous pouvez faire défiler la page derrière ce panneau. Sans fond, le focus n'est pas piégé.
Défilement avec fond
La page défile et le fond reste cliquable pour fermer.
Fond statique
Un clic à l'extérieur ne ferme pas ce panneau.
<div class="d-flex flex-wrap gap-2">
  <button class="btn btn-outline-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-defilement" data-bs-scroll="true" data-bs-backdrop="false">Défilement, sans fond</button>
  <button class="btn btn-outline-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-defilement-fond" data-bs-scroll="true">Défilement, avec fond</button>
  <button class="btn btn-outline-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-statique" data-bs-backdrop="static">Fond statique</button>
</div>

<div class="offcanvas offcanvas-start" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1" id="offcanvas-defilement" aria-labelledby="offcanvas-defilement-titre">
  <div class="offcanvas-header">
    <h2 class="offcanvas-title fs-5" id="offcanvas-defilement-titre">Page défilable</h2>
    <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Fermer"></button>
  </div>
  <div class="offcanvas-body">Vous pouvez faire défiler la page derrière ce panneau. Sans fond, le focus n'est pas piégé.</div>
</div>
<div class="offcanvas offcanvas-start" data-bs-scroll="true" tabindex="-1" id="offcanvas-defilement-fond" aria-labelledby="offcanvas-defilement-fond-titre">
  <div class="offcanvas-header">
    <h2 class="offcanvas-title fs-5" id="offcanvas-defilement-fond-titre">Défilement avec fond</h2>
    <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Fermer"></button>
  </div>
  <div class="offcanvas-body">La page défile et le fond reste cliquable pour fermer.</div>
</div>
<div class="offcanvas offcanvas-end" data-bs-backdrop="static" tabindex="-1" id="offcanvas-statique" aria-labelledby="offcanvas-statique-titre">
  <div class="offcanvas-header">
    <h2 class="offcanvas-title fs-5" id="offcanvas-statique-titre">Fond statique</h2>
    <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Fermer"></button>
  </div>
  <div class="offcanvas-body">Un clic à l'extérieur ne ferme pas ce panneau.</div>
</div>

Couleurs#

Pour un panneau foncé, ajoutez .text-bg-dark et utilisez .btn-close-white pour que le bouton de fermeture reste visible.

Notifications
Virement de 75 000 FCFA reçu ce matin.
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-sombre">Panneau foncé</button>

<div class="offcanvas offcanvas-end text-bg-dark" tabindex="-1" id="offcanvas-sombre" aria-labelledby="offcanvas-sombre-titre">
  <div class="offcanvas-header">
    <h2 class="offcanvas-title fs-5" id="offcanvas-sombre-titre">Notifications</h2>
    <button type="button" class="btn-close btn-close-white" data-bs-dismiss="offcanvas" aria-label="Fermer"></button>
  </div>
  <div class="offcanvas-body">Virement de 75 000 FCFA reçu ce matin.</div>
</div>

Offcanvas responsive#

Remplacez .offcanvas par .offcanvas-{sm|md|lg|xl|xxl} : sous le point de rupture, le contenu est un panneau ; au-dessus, il s’affiche dans la page. Le bouton déclencheur doit alors être masqué avec d-lg-none.

Affichage large : le contenu ci-dessous est dans la page, sans panneau.
Filtres
<button class="btn btn-primary d-lg-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvas-adaptatif" aria-controls="offcanvas-adaptatif">Afficher les filtres</button>

<div class="alert alert-info d-none d-lg-block mb-0">Affichage large : le contenu ci-dessous est dans la page, sans panneau.</div>

<div class="offcanvas-lg offcanvas-end" tabindex="-1" id="offcanvas-adaptatif" aria-labelledby="offcanvas-adaptatif-titre">
  <div class="offcanvas-header">
    <h2 class="offcanvas-title fs-5" id="offcanvas-adaptatif-titre">Filtres</h2>
    <button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#offcanvas-adaptatif" aria-label="Fermer"></button>
  </div>
  <div class="offcanvas-body">
    <label class="form-label" for="offcanvas-filtre-type">Type d'opération</label>
    <select class="form-select" id="offcanvas-filtre-type">
      <option>Toutes</option>
      <option>Virements</option>
      <option>Retraits</option>
    </select>
  </div>
</div>

Utilisation en JavaScript#

Ouvrez ou fermez le panneau depuis votre code et réagissez à ses événements.

const element = document.getElementById('offcanvas-bouton');
const panneau = new bootstrap.Offcanvas(element, {
  backdrop: 'static',
  scroll: false,
  keyboard: true,
});

panneau.show();

element.addEventListener('hidden.bs.offcanvas', () => {
  console.log('Panneau fermé');
});

// Plus tard
panneau.hide();

Options

Options passées au constructeur ou par attribut (data-bs-backdrop, data-bs-keyboard, data-bs-scroll) sur le panneau ou sur son déclencheur.

Options
OptionTypeDéfautDescription
backdropboolean | 'static'trueAffiche un fond. 'static' : le fond ne ferme pas le panneau ; false : pas de fond.
keyboardbooleantrueFerme le panneau avec la touche Échap.
scrollbooleanfalseAutorise le défilement de la page pendant que le panneau est ouvert.

Méthodes

Méthodes
MéthodeDescription
toggle(relatedTarget)Ouvre ou ferme le panneau.
show(relatedTarget)Ouvre le panneau.
hide()Ferme le panneau.
dispose()Détruit l’instance.
bootstrap.Offcanvas.getInstance(element)Renvoie l’instance liée à l’élément, ou null.
bootstrap.Offcanvas.getOrCreateInstance(element, options)Renvoie l’instance, ou la crée.

Événements

Événements
ÉvénementDéclenché quand
show.bs.offcanvasL’ouverture est demandée. relatedTarget contient le déclencheur.
shown.bs.offcanvasLe panneau est visible, transition terminée.
hide.bs.offcanvasLa fermeture est demandée.
hidePrevented.bs.offcanvasLa fermeture est bloquée (fond statique ou preventDefault()).
hidden.bs.offcanvasLe panneau est fermé, transition terminée.

Classes et attributs data-bs-*

Classes et attributs data-bs-*
ÉlémentRôle
.offcanvas, .offcanvas-{sm|md|lg|xl|xxl}Le panneau (toujours, ou seulement sous le point de rupture).
.offcanvas-start, .offcanvas-end, .offcanvas-top, .offcanvas-bottomBord d’où le panneau apparaît.
.offcanvas-header, .offcanvas-title, .offcanvas-bodyEn-tête, titre et corps (le corps défile si le contenu est long).
data-bs-toggle="offcanvas"Sur le déclencheur : ouvre ou ferme le panneau ciblé.
data-bs-target="#id"Sur le déclencheur : sélecteur du panneau.
data-bs-dismiss="offcanvas"Sur un bouton du panneau : le ferme.
data-bs-backdrop, data-bs-keyboard, data-bs-scrollOptions du panneau.

Variables Sass

Variables Sass
VariableValeur par défaut
$offcanvas-padding-y$modal-inner-padding (1 rem)
$offcanvas-padding-x$modal-inner-padding (1 rem)
$offcanvas-horizontal-width400px
$offcanvas-vertical-height30vh
$offcanvas-transition-duration.3s
$offcanvas-border-color$modal-content-border-color
$offcanvas-bg-colorvar(--bs-body-bg)
$offcanvas-colorvar(--bs-body-color)
$offcanvas-box-shadow$modal-content-box-shadow-xs
$offcanvas-backdrop-bg$modal-backdrop-bg (noir)
$offcanvas-backdrop-opacity.5

Personnalisation#

Les variables CSS --bs-offcanvas-* se surchargent sur le panneau concerné.

// Sass : panneaux latéraux plus étroits
$offcanvas-horizontal-width: 320px;
$offcanvas-backdrop-opacity: 0.4;

// CSS : un panneau précis
.panneau-filtres {
  --bs-offcanvas-width: 360px;
  --bs-offcanvas-padding-x: 1.5rem;
  --bs-offcanvas-bg: #F5F7FA;
}

Bonnes pratiques

À faire

  • Utilisez l’offcanvas pour du contenu secondaire : menu mobile, filtres, panier, aide.
  • Donnez un titre au panneau et reliez-le avec aria-labelledby.
  • Placez le panneau du côté où l’utilisateur l’attend : menu à gauche, panier ou notifications à droite.
  • Gardez un bouton de fermeture visible, même si Échap fonctionne.

À éviter

  • Ne l’utilisez pas pour une confirmation qui exige une réponse : préférez une modale.
  • Ne placez pas de formulaires longs dans un panneau étroit.
  • N’ouvrez pas un panneau automatiquement au chargement de la page.

Accessibilité

  • À l’ouverture, Cauri ajoute role="dialog" et aria-modal="true" et pose le focus sur le panneau ; à la fermeture, le focus revient au déclencheur.
  • Le focus est piégé dans le panneau tant que le fond est actif ou que scroll est faux. Avec data-bs-scroll="true" et data-bs-backdrop="false", le focus circule librement : fournissez alors un moyen de fermeture évident.
  • Échap ferme le panneau, sauf si keyboard vaut false.
  • Mettez tabindex="-1" sur le panneau pour qu’il puisse recevoir le focus.
  • Un bouton .btn-close sans texte doit avoir un aria-label.
Charte provisoire, déduite du site public de la BDU CI. Elle sera remplacée par la charte officielle.