Drawer
Neu in Bootstrap v6.0.0
Ausblendbare Seitenleisten für Navigation, Warenkorb und mehr – der Drawer ist in Bootstrap 6 der Nachfolger der Offcanvas-Komponente.
Statt eines <div> mit eigener Overlay-Logik nutzt der Drawer das native <dialog>-Element und teilt sich die Basis mit der neuen Dialog-Komponente. Fokusfalle, Backdrop und Top Layer liefert damit der Browser.
- Vier Seiten plus Vollbild:
.drawer-start,-end,-top,-bottomund.drawer-fullscreen. - Wischen zum Schließen: passend zur jeweiligen Position.
- Responsive:
.lg:drawer& Co. sind unterhalb des Breakpoints Drawer, darüber normaler Inhalt. - Varianten: dunkel, durchscheinend, bündig als Sheet oder ohne Animation.
Quelle: Bootstrap-Dokumentation (englisch), übersetzt und bearbeitet. Doku lizenziert unter CC BY 3.0.
Funktionsweise
Der Drawer baut auf dem nativen <dialog>-Element und der Dialog-Komponente auf und blendet Seitenleisten per JavaScript ein und aus. Drawer können vom linken, rechten, oberen oder unteren Rand des Viewports kommen. Buttons oder Links dienen als Auslöser, data-Attribute rufen das JavaScript auf.
- Gleiche Basis wie der Dialog: Fokusfalle, Backdrop und Top Layer kommen über die nativen
<dialog>-APIs. - Nutze
<dialog>, kein<div>. Wegen der CSS-Animationen gehörenmarginodertranslatenicht direkt an.drawer– setze bei Bedarf einen Wrapper drumherum. - Standardmäßig modal: öffnet per
showModal()mit Backdrop und Fokusfalle. Mitscroll: trueundbackdrop: falseöffnet er pershow()nicht-modal – die Seite bleibt scrollbar, der Fokus wird nicht festgehalten. - Eingebauter Backdrop über
::backdrop(nur modal), ein Klick darauf schließt.backdrop: "static"sperrt Klicks außerhalb,backdrop: falseblendet ihn aus. - Escape-Taste schließt standardmäßig;
keyboard: falseschaltet das ab. - Wischen zum Schließen: passend zur Position (z. B. nach links wischen bei
drawer-startin LTR, nach unten beidrawer-bottom). - Responsive Platzierung:
.sm:drawer,.md:drawerusw. verhalten sich unterhalb des Breakpoints wie ein Drawer und darüber wie normaler Inhalt – ideal für responsive Navbars. - Nur ein Drawer gleichzeitig (sorgt die Data-API dafür).
- Animiertes Öffnen und Schließen: Beim Schließen fährt der Drawer zurück an seine Ausgangsposition, der
::backdropblendet modal mit aus. Eigene[open]-Regeln solltest du mit:not(.hiding)einschränken;.drawer-instantschaltet die Animationen ab.
Die Animation richtet sich nach der Media Query prefers-reduced-motion.
Beispiele
Bestandteile
Das folgende Beispiel ist von vornherein sichtbar (über open und .show am <dialog>). Ein Drawer hat einen Kopfbereich mit Schließen-Button und optional einen Body mit etwas Innenabstand. Biete möglichst immer einen Kopfbereich mit Schließen-Aktion oder eine andere eindeutige Möglichkeit zum Schließen an.
<dialog class="drawer drawer-start show" open tabindex="-1" id="drawer" aria-labelledby="drawerLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerLabel">Drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
Hier steht der Inhalt des Drawers. Du kannst nahezu jede Bootstrap-Komponente oder eigene Elemente einsetzen.
</div>
</dialog>Live-Demo
Die Buttons unten blenden einen Drawer per JavaScript ein und aus. Du kannst einen Link mit href oder einen Button mit data-bs-target verwenden – data-bs-toggle="drawer" ist in beiden Fällen Pflicht.
<a class="btn-solid theme-primary" data-bs-toggle="drawer" href="#drawerExample" role="button" aria-controls="drawerExample">
Link mit href
</a>
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerExample" aria-controls="drawerExample">
Button mit data-bs-target
</button>
<dialog class="drawer drawer-start" tabindex="-1" id="drawerExample" aria-labelledby="drawerExampleLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerExampleLabel">Drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
<div>
Etwas Platzhaltertext. In der Praxis stehen hier deine eigenen Elemente – Text, Bilder, Listen usw.
</div>
<div class="mt-3">
<button class="btn-solid theme-secondary" type="button" data-bs-toggle="menu">
Menü
</button>
<div class="menu">
<a class="menu-item" href="#">Aktion</a>
<a class="menu-item" href="#">Weitere Aktion</a>
<a class="menu-item" href="#">Noch etwas anderes</a>
</div>
</div>
</div>
</dialog>Ohne JavaScript
In unterstützten Browsern öffnest und schließt du einen Drawer über die Invoker Commands API, ganz ohne Bootstrap-JavaScript: commandfor zeigt auf die id des Drawers, command="show-modal" öffnet, command="close" schließt.
Die Invoker Commands API wird nicht von allen Browsern unterstützt. Brauchst du verlässliche Unterstützung, Plugin-Optionen, Events, Wischen zum Schließen oder animiertes Schließen, nimm die Varianten mit data-bs-toggle.
<button type="button" class="btn-solid theme-primary" commandfor="invokerDrawer" command="show-modal">
Drawer öffnen
</button>
<dialog class="drawer drawer-start" tabindex="-1" id="invokerDrawer" aria-labelledby="invokerDrawerLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="invokerDrawerLabel">Invoker Commands</h5>
<button type="button" class="btn-close" commandfor="invokerDrawer" command="close" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
<p>Dieser Drawer öffnet mit <code>command="show-modal"</code> und schließt mit <code>command="close"</code> – ganz ohne Bootstrap-JavaScript.</p>
</div>
</dialog>Scrollen und Backdrop
Seite scrollen
Öffnet ein Drawer modal, ist das Scrollen von <body> gesperrt. Mit data-bs-scroll="true" und data-bs-backdrop="false" bleibt die Seite scrollbar und der Drawer öffnet nicht-modal. Der Fokus wandert in den Drawer, wird aber nicht festgehalten.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerScrolling" aria-controls="drawerScrolling">Scrollen der Seite erlauben</button>
<dialog class="drawer drawer-start" data-bs-scroll="true" data-bs-backdrop="false" tabindex="-1" id="drawerScrolling" aria-labelledby="drawerScrollingLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerScrollingLabel">Drawer mit scrollbarer Seite</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
<p>Scrolle die restliche Seite, um die Option in Aktion zu sehen.</p>
</div>
</dialog>Scrollen mit Backdrop
Du kannst das Scrollen auch mit Backdrop erlauben. Mit Backdrop bleibt der Drawer modal (showModal() und Fokusfalle), selbst wenn scroll auf true steht.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerWithBothOptions" aria-controls="drawerWithBothOptions">Scrollen und Backdrop aktivieren</button>
<dialog class="drawer drawer-start" data-bs-scroll="true" tabindex="-1" id="drawerWithBothOptions" aria-labelledby="drawerWithBothOptionsLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerWithBothOptionsLabel">Backdrop mit Scrollen</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
<p>Scrolle die restliche Seite, um die Option in Aktion zu sehen.</p>
</div>
</dialog>Statischer Backdrop
Mit static als Backdrop schließt ein Klick außerhalb den Drawer nicht.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#staticBackdrop" aria-controls="staticBackdrop">
Statischen Drawer umschalten
</button>
<dialog class="drawer drawer-start" data-bs-backdrop="static" tabindex="-1" id="staticBackdrop" aria-labelledby="staticBackdropLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="staticBackdropLabel">Drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
<div>
Ein Klick außerhalb schließt mich nicht.
</div>
</div>
</dialog>Drawer ohne Animation
Standardmäßig gleiten Drawer beim Öffnen und Schließen. .drawer-instant am <dialog> schaltet die Animation ab.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#instantDrawer" aria-controls="instantDrawer">
Drawer ohne Animation umschalten
</button>
<dialog class="drawer drawer-start drawer-instant" tabindex="-1" id="instantDrawer" aria-labelledby="instantDrawerLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="instantDrawerLabel">Drawer ohne Animation</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
<p>Dieser Drawer erscheint und verschwindet sofort, ohne Animation.</p>
</div>
</dialog>Dunkler Drawer
Mit data-bs-theme="dark" am .drawer laufen alle enthaltenen Elemente im dunklen Modus – passend etwa zu dunklen Navbars.
<dialog class="drawer drawer-start show" open tabindex="-1" id="drawerDark" aria-labelledby="drawerDarkLabel" data-bs-theme="dark">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerDarkLabel">Drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
<p>Hier steht der Inhalt des Drawers.</p>
</div>
</dialog>Durchscheinender Drawer
.drawer-translucent macht das Panel halbtransparent: Der Hintergrund dahinter wird weichgezeichnet und kräftiger gefärbt.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerTranslucent" aria-controls="drawerTranslucent">
Durchscheinenden Drawer umschalten
</button>
<dialog class="drawer drawer-start drawer-translucent" tabindex="-1" id="drawerTranslucent" aria-labelledby="drawerTranslucentLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerTranslucentLabel">Durchscheinender Drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
Inhalt des durchscheinenden Drawers. Was dahinter liegt, wird unscharf und farbintensiver dargestellt.
</div>
</dialog>Sheet
.drawer-sheet setzt das Panel bündig an den Viewport-Rand. Abstand, Rahmen, Rundung und Schatten entfallen – wie beim klassischen Offcanvas. Funktioniert mit jeder Platzierung.
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerSheet" aria-controls="drawerSheet">
Sheet-Drawer umschalten
</button>
<dialog class="drawer drawer-bottom drawer-sheet" tabindex="-1" id="drawerSheet" aria-labelledby="drawerSheetLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerSheetLabel">Sheet-Drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
Inhalt des Sheet-Drawers. Er liegt bündig am Rand – ohne Abstand, Rahmen, Rundung oder Schatten.
</div>
</dialog>Responsive
Responsive Drawer-Klassen verstecken den Inhalt ab einem Breakpoint abwärts außerhalb des Viewports. Oberhalb davon verhält sich der Inhalt normal. .lg:drawer etwa ist unterhalb von lg ein Drawer und darüber regulär sichtbar. Diese Klassen gibt es für jeden Breakpoint.
Ersetze dafür die Basisklasse .drawer durch die responsive Variante. Schließen-Buttons im Drawer funktionieren ohne eigenes data-bs-target.
Verkleinere das Browserfenster, um den Button für den responsiven Drawer zu sehen.
<button class="btn-solid theme-primary lg:d-none" type="button" data-bs-toggle="drawer" data-bs-target="#drawerResponsive" aria-controls="drawerResponsive">Drawer umschalten</button>
<div class="alert theme-info d-none lg:d-block mb-3"><p>Verkleinere das Browserfenster, um den Button für den responsiven Drawer zu sehen.</p></div>
<dialog class="lg:drawer drawer-end" tabindex="-1" id="drawerResponsive" aria-labelledby="drawerResponsiveLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerResponsiveLabel">Responsiver Drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
<p class="mb-0">Das ist Inhalt in einem <code>.lg:drawer</code>.</p>
</div>
</dialog>Platzierung
Eine Standardposition gibt es nicht – du musst eine der folgenden Klassen setzen:
.drawer-start: links im Viewport (siehe oben).drawer-end: rechts.drawer-top: oben.drawer-bottom: unten.drawer-fullscreen: füllt den gesamten Viewport
Probiere oben, rechts, unten und Vollbild aus:
<button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerTop" aria-controls="drawerTop">Drawer oben umschalten</button>
<dialog class="drawer drawer-top" tabindex="-1" id="drawerTop" aria-labelledby="drawerTopLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerTopLabel">Drawer oben</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
...
</div>
</dialog><button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerRight" aria-controls="drawerRight">Drawer rechts umschalten</button>
<dialog class="drawer drawer-end" tabindex="-1" id="drawerRight" aria-labelledby="drawerRightLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerRightLabel">Drawer rechts</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
...
</div>
</dialog><button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerBottom" aria-controls="drawerBottom">Drawer unten umschalten</button>
<dialog class="drawer drawer-bottom" tabindex="-1" id="drawerBottom" aria-labelledby="drawerBottomLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerBottomLabel">Drawer unten</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body small">
...
</div>
</dialog><button class="btn-solid theme-primary" type="button" data-bs-toggle="drawer" data-bs-target="#drawerFullscreen" aria-controls="drawerFullscreen">Vollbild-Drawer umschalten</button>
<dialog class="drawer drawer-fullscreen" tabindex="-1" id="drawerFullscreen" aria-labelledby="drawerFullscreenLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerFullscreenLabel">Vollbild-Drawer</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
<p>Dieser Drawer füllt den gesamten Viewport – praktisch für ganzseitige Menüs oder Modal-ähnliche Ansichten.</p>
</div>
</dialog>Fußbereich
Ein optionales .drawer-footer nimmt Aktions-Buttons oder anderen Inhalt am unteren Ende auf.
<dialog class="drawer drawer-start show" open tabindex="-1" id="drawerFooter" aria-labelledby="drawerFooterLabel">
<div class="drawer-header">
<h5 class="drawer-title" id="drawerFooterLabel">Drawer mit Fußbereich</h5>
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Schließen"></button>
</div>
<div class="drawer-body">
<p>Hier steht der Inhalt des Drawers. Der Fußbereich bleibt unten.</p>
</div>
<div class="drawer-footer">
<button type="button" class="btn-solid theme-secondary" data-bs-dismiss="drawer">Schließen</button>
<button type="button" class="btn-solid theme-primary">Änderungen speichern</button>
</div>
</dialog>Verwendung
Das Drawer-Plugin baut auf <dialog> auf und kommt mit wenigen Klassen und Attributen aus:
.draweran einem<dialog>aktiviert das Drawer-Verhalten.drawer-start: links.drawer-end: rechts.drawer-top: oben.drawer-bottom: unten
Einen Schließen-Button versiehst du mit data-bs-dismiss="drawer". Verwende dafür ein <button>-Element, damit es auf allen Geräten zuverlässig funktioniert.
Per Data-Attribute
| Attribut | Beschreibung |
|---|---|
data-bs-toggle="drawer" | Aktiviert das Drawer-Verhalten am Auslöser. |
data-bs-target | CSS-Selektor des zu öffnenden <dialog>-Drawers (bei Links alternativ href). |
data-bs-dismiss="drawer" | An einem Schließen-Element: schließt den Drawer beim Aktivieren. |
Umschalten
Mit data-bs-toggle="drawer" plus data-bs-target oder href steuert ein Element automatisch einen Drawer. data-bs-target nimmt einen CSS-Selektor. Das Ziel muss ein <dialog> mit der Klasse drawer sein.
Schließen
Geschlossen wird über data-bs-dismiss an einem Button innerhalb des Drawers:
<button type="button" class="btn-close" data-bs-dismiss="drawer" aria-label="Close"></button>oder an einem Button außerhalb des Drawers mit zusätzlichem data-bs-target:
<button type="button" class="btn-close" data-bs-dismiss="drawer" data-bs-target="#my-drawer" aria-label="Close"></button>Beide Wege werden unterstützt. Das Schließen von außerhalb entspricht aber nicht dem Dialog-(Modal-)Muster des ARIA Authoring Practices Guide – nutze es auf eigenes Risiko.
Per JavaScript
Manuell aktivierst du Drawer so:
const drawerElementList = document.querySelectorAll('dialog.drawer')
const drawerList = [...drawerElementList].map(drawerEl => new bootstrap.Drawer(drawerEl))Optionen
Optionen übergibst du per Data-Attribut (data-bs- + Optionsname, z. B. data-bs-backdrop="static") oder per JavaScript.
| Name | Typ | Standard | Beschreibung |
|---|---|---|---|
backdrop | boolean oder der String static | true | Legt beim geöffneten Drawer einen Backdrop über die Seite. Mit static schließt ein Klick darauf den Drawer nicht. |
keyboard | boolean | true | Schließt den Drawer mit der Escape-Taste. |
scroll | boolean | false | Erlaubt das Scrollen der Seite bei geöffnetem Drawer. Zusammen mit backdrop: false öffnet der Drawer nicht-modal (ohne Fokusfalle). |
Methoden
Methoden zum Ein- und Ausblenden liefern ein Promise. Es wird erfüllt, wenn der Übergang endet – await läuft also im selben Moment weiter wie ein Listener auf shown.bs.* bzw. hidden.bs.*. Die Methoden kehren trotzdem sofort zurück und blockieren nicht. Ein Aufruf während eines laufenden Übergangs bewirkt nichts und wird sofort erfüllt.
Macht deinen Inhalt zum Drawer; optional mit Options-object. Eine Instanz erzeugst du z. B. so:
const bsDrawer = new bootstrap.Drawer('#myDrawer')| Methode | Beschreibung |
|---|---|
dispose | Entfernt die Drawer-Instanz eines Elements. |
getInstance | Statisch: liefert die Drawer-Instanz zu einem DOM-Element. |
getOrCreateInstance | Statisch: liefert die Instanz oder legt eine neue an, falls noch keine existiert. |
hide | Blendet den Drawer aus. Liefert ein Promise, das nach dem Ausblenden erfüllt wird (nach hidden.bs.drawer). |
show | Blendet den Drawer ein. Liefert ein Promise, das nach dem Einblenden erfüllt wird (nach shown.bs.drawer). |
toggle | Schaltet den Drawer um. Liefert ein Promise, das nach dem Ein- bzw. Ausblenden erfüllt wird. |
Events
Die Drawer-Klasse stellt folgende Events bereit:
| Event | Beschreibung |
|---|---|
hide.bs.drawer | Wird sofort beim Aufruf der Methode hide ausgelöst. |
hidden.bs.drawer | Wird ausgelöst, wenn der Drawer vollständig ausgeblendet ist (nach Abschluss der CSS-Übergänge). |
hidePrevented.bs.drawer | Wird ausgelöst, wenn bei statischem Backdrop außerhalb geklickt oder bei keyboard: false Escape gedrückt wird. |
show.bs.drawer | Wird sofort beim Aufruf der Methode show ausgelöst. |
shown.bs.drawer | Wird ausgelöst, wenn der Drawer sichtbar ist (nach Abschluss der CSS-Übergänge). |
const myDrawer = document.getElementById('myDrawer')
myDrawer.addEventListener('hidden.bs.drawer', event => {
// do something...
})CSS-Variablen sowie die Sass-Tokens für Drawer und Backdrop findest du in der Originaldokumentation.
Barrierefreiheit
Als natives <dialog> bekommt der Drawer automatisch die Rolle dialog.
- Modale Drawer erhalten über
showModal()zusätzlich modale Semantik und eine Fokusfalle. - Nicht-modale Drawer (
scroll: trueundbackdrop: false) öffnen pershow()– sie halten den Fokus nicht fest und machen den Rest der Seite nicht inaktiv. - Verweise mit
aria-labelledbyauf den Titel des Drawers.