Bootstrap 5 Offcanvas JS vs Native <dialog> element
dialog.showModal() / dialog.close() which
provides backdrop, focus trap, and scroll lock natively. CSS transitions are disabled
during the run so we measure raw JS overhead, not animation time.
Uses bootstrap.Offcanvas — creates backdrop divs, manages focus traps, toggles scroll locks via JavaScript.
Uses dialog.showModal() / dialog.close() — browser handles backdrop, focus trap, and scroll lock natively. Zero JS dependencies.
| Metric | Bootstrap Offcanvas | Native <dialog> |
|---|---|---|
| Initialization time | - | - |
| Toggle time (500 open/close cycles) | - | - |
| Instance memory cost | - | - |
| JS code size | - | - |
|
CSS output size
_offcanvas.scss (4.7 KB)
|
- | - |
<dialog> vs Bootstrap OffcanvasClick the buttons below to compare the animation feel. Both slide in from the left with a 0.3s ease transition. The native side uses only CSS.
@starting-style + transition)
<div>, manages focus trap, toggles scroll lock, applies
CSS transforms via .offcanvas.showing / .offcanvas.hiding classes).
Native <dialog> opens instantly by default.
However, native <dialog> can achieve the same smooth slide-in animation
using pure CSS via @starting-style and transition — zero JavaScript required.
The benchmark above disables all transitions to measure raw JS overhead only.
<!-- Native dialog styled as offcanvas (Bootstrap utility classes) -->
<dialog class="animated-offcanvas position-fixed top-0 start-0 bottom-0
m-0 h-100 border-0 p-0 bg-white shadow-lg"
style="width: 400px; max-height: 100dvh;"
id="myDialog">
<div class="d-flex align-items-center p-3 border-bottom">
<h5 class="mb-0 me-auto">Title</h5>
<button class="btn-close" onclick="myDialog.close()"></button>
</div>
<div class="p-3 overflow-auto flex-grow-1">
Content here...
</div>
</dialog>
<!-- Open: myDialog.showModal() Close: myDialog.close() -->
dialog.animated-offcanvas[open] {
display: flex;
flex-direction: column;
}
/* Slide-in from left, same as Bootstrap offcanvas */
dialog.animated-offcanvas {
transition: translate 0.3s ease,
display 0.3s ease allow-discrete,
overlay 0.3s ease allow-discrete;
translate: -100% 0;
}
dialog.animated-offcanvas[open] { translate: 0 0; }
@starting-style {
dialog.animated-offcanvas[open] { translate: -100% 0; }
}
/* Backdrop fade */
dialog.animated-offcanvas::backdrop {
transition: background-color 0.3s ease,
display 0.3s ease allow-discrete,
overlay 0.3s ease allow-discrete;
background-color: transparent;
}
dialog.animated-offcanvas[open]::backdrop {
background-color: rgba(0, 0, 0, 0.5);
}
@starting-style {
dialog.animated-offcanvas[open]::backdrop {
background-color: transparent;
}
}
This panel is rendered by Bootstrap’s Offcanvas JS plugin.
It creates a backdrop <div>, activates a JavaScript focus trap, and disables body scroll via ScrollBarHelper.
This panel uses Bootstrap’s JavaScript Offcanvas plugin.
Each open/close triggers:
<div> created & appended to bodyfocusin + keydown)ScrollBarHelper (calculates scrollbar width, sets overflow: hidden).showing, .hiding, .show)show, shown, hide, hidden)