Does Bootstrap Have a Built-In Sidebar Component?
No. Every Bootstrap sidebar is pieced together from other parts of the framework, and the docs treat it as a pattern, not a component. The example gallery has a Sidebars example aimed at offcanvas and multi-column layouts, plus a Dashboard example that pairs a fixed sidebar with a navbar.
It goes by a lot of names. Side navbar, sidenav, vertical navigation, off-canvas menu. Outside Bootstrap, design systems often call the slide-in version a drawer.
Third parties fill the gap. CoreUI’s documentation defines a .sidebar wrapper with header, brand, nav and footer parts, hidden by default on mobile and shown by default on desktop.
That’s CoreUI’s component, not Bootstrap’s. Its class names do nothing in a plain Bootstrap install.
Which Bootstrap Sidebar Method Fits Your Layout?
Flexbox covers a sidebar that never hides. Offcanvas handles one that has to slide in on small screens, horizontal collapse suits a desktop toggle, and a template makes sense once menus run deeper than two levels.
| Method | Mobile behavior | JavaScript | Best fit |
|---|
| Flexbox layout | Stays visible or hides with display utilities | None | Static admin or docs pages |
| Offcanvas | Slides over the content, optional backdrop | Bootstrap Offcanvas plugin | Sidebar that hides on small screens |
| Horizontal collapse | Shrinks or hides by width | Bootstrap Collapse plugin | Desktop toggle, icon-only mode |
| Template | Built in, varies by template | The template’s own script | Multi-level menus, mini sidebar |
Pick by requirement, not by popularity. A sidebar that never hides needs flex utilities and nothing else, so no plugin has to load for it. If it only hides on mobile, a responsive offcanvas class does the job. Horizontal collapse suits users who toggle the sidebar on desktop, and you add your own CSS if you want an icon-only strip. Deep menus or a hover-expand mini mode are faster to get from a template than to build by hand.
Offcanvas is the popular choice and often the wrong one for a sidebar that never hides.
It works like a modal, hidden until activated, and Bootstrap’s documentation notes that body scrolling is disabled while an offcanvas and its backdrop are visible. A permanent column gains nothing from that.
How to Build the Base Sidebar Layout
The layout holds with a handful of flex classes. d-flex goes on the wrapper, flex-column on the sidebar and flex-grow-1 on the main area. Add a fixed width and a height class and you’re done.
- Load the Bootstrap 5 CSS and
bootstrap.bundle.min.js. The bundle includes Popper, which dropdowns rely on. - Wrap the sidebar and the main area in one div with the class
d-flex. - Make the sidebar a nav element with
d-flex flex-column flex-shrink-0 p-3 bg-body-tertiary and a fixed width. 280px is a common starting point. - Fill it with a
nav nav-pills flex-column list, where each link gets nav-link. - Give the main area
flex-grow-1 so it takes the remaining width. - Add
vh-100 to the sidebar, or min-vh-100 to the wrapper, so the column reaches the bottom of the screen.
Skip the height class and the sidebar ends where its content ends. Skip flex-shrink-0 and a wide table in the main area can squeeze the column below its set width.
Fixed or Sticky Positioning
A fixed sidebar uses position-fixed top-0 bottom-0 start-0 to pin itself to the viewport. Fixed elements leave the document flow, so the main area needs a left margin equal to the sidebar width.
Sticky works differently. sticky-top plus vh-100 keeps the sidebar in view while the page scrolls, and since it stays in the flow, no offset is needed.
Sticky quietly fails when any ancestor sets overflow to hidden, scroll or auto. Check the wrapper before blaming the classes.
Scrolling Long Menus
Put overflow-auto on the link list, not on the whole sidebar. The brand and any user menu then stay pinned while the links scroll.
Bootstrap’s vh-100 maps to 100vh, one of the viewport height units. On mobile browsers 100vh can run under the address bar, which pushes the last links offscreen.
A custom height: 100dvh rule fixes that in current browsers.
How to Make a Bootstrap Sidebar Responsive With Offcanvas
Replace .offcanvas with .offcanvas-lg on the sidebar. The same markup then renders as a static column at 992px and wider and as a slide-in panel below that, per the Bootstrap documentation.
The panel gets offcanvas-lg offcanvas-start along with an id, tabindex="-1" and aria-labelledby. The toggle is a button with d-lg-none, data-bs-toggle="offcanvas", data-bs-target and aria-controls. For closing, use a btn-close with data-bs-dismiss="offcanvas" and an explicit data-bs-target.
That last attribute is easy to miss. Bootstrap’s docs say a responsive offcanvas needs the close button to carry its own target, and without it the button can fail to close the panel.
The toggle is usually a hamburger menu icon in a slim top bar. The data-bs-toggle attribute is required on it.
A navbar can carry the same toggle. Bootstrap’s navbar offcanvas example hides the toggle once the viewport reaches the navbar-expand-* breakpoint, so a Bootstrap navbar with navbar-expand-lg shows the toggle below 992px and can sit above or beside the sidebar and open it.
Choosing the Breakpoint
The responsive variants run from .offcanvas-sm up to .offcanvas-xxl. Pick the one where the sidebar and the content stop fitting side by side.
A lower breakpoint keeps the sidebar on screen longer, at the cost of a narrower content column. A higher one slides the panel in earlier and gives the content more room.
Bootstrap’s breakpoint mixins subtract .02px for max-width rules, according to the breakpoints documentation. The lg panel therefore switches at 991.98px, not 992px, which matters when you test at exact widths.
Setting the Panel Width
The default panel is 400px wide, set by $offcanvas-horizontal-width in Bootstrap’s Sass. That’s wide for a menu.
Override the Sass variable before the import, or set --bs-offcanvas-width on the element. Set the desktop width on the sidebar itself with a width utility or inline style, so it does not depend on the offcanvas variable.
One documented limit. You cannot use margin or translate on an .offcanvas element, because they clash with how the panel animates. Push the main content with its own wrapper instead.
As of October 2026, Bootstrap 5 is still supported and 5.3.8 is the current release. The first Bootstrap 6 alpha (October 8, 2026) moves customization to token maps, so Sass overrides written for version 5 will need rewriting after an upgrade (Bootstrap blog).
How to Collapse and Expand the Sidebar on Desktop
Wrap the sidebar in a collapse collapse-horizontal show element, give its immediate child a fixed width, and point a toggle button at it with data-bs-toggle="collapse". Bootstrap’s documentation says only the width on the child is required, and the transition runs 0.35 seconds by default.
The button carries data-bs-target with the wrapper’s id, plus aria-controls. The plugin keeps aria-expanded in sync when the toggle is wired through the data attributes.
Make the main area flex-grow-1. It then widens on its own as the sidebar shrinks.
Bootstrap has no icon-only mode. Horizontal collapse animates to zero width, so a mini sidebar needs your own class that narrows the column and hides the text labels.
A media query can start the page in the narrow state on mid-sized screens, and a CSS width transition smooths the change.
To remember the state between visits, save the open or closed value in localStorage when the collapse fires shown.bs.collapse or hidden.bs.collapse. Read it back in a small script placed right after the sidebar markup, so the panel paints in the saved state and does not flash.
localStorage keeps data across browser sessions, according to MDN Web Docs. It also has limits you need to plan for. Private browsing clears it when the last private tab closes, and http and https versions of a site get separate storage objects. Access can throw a SecurityError too, so wrap reads and writes in try/catch.
The sidebar must still render in a sensible default state when storage is blocked. Treat the saved value as a preference, never as a requirement.
How to Add Submenus and an Active Link State
Point each parent link at a nested nav list with the collapse plugin, then mark the current page with the active class and aria-current="page". Bootstrap’s navs documentation says the base nav component has no active state of its own, so you set it.
For the submenu, the parent is a link or button with data-bs-toggle="collapse" and a matching data-bs-target. The child is a collapse element holding a second nav flex-column list, indented with ms-3. Add show to the child if it should start open.
Add data-bs-parent pointing at the sidebar list and opening one submenu closes the others. That gives you accordion-style grouping without the accordion’s visual styling.
Leave the attribute out, as the docs’ always-open accordion example does, and several submenus stay open together.
A dropdown flyout is the other route. In a vertical sidebar it opens over the content, while an in-place collapse keeps the list readable.
List groups work as alternative markup. list-group-item-action links stack with borders, and the active rules stay identical.
For the active link itself, compare each link’s path with window.location.pathname on load, after trimming trailing slashes (/docs and /docs/ are different strings). Add active and aria-current="page" to the match and strip both from the previous link. If the match sits inside a submenu, add show to that submenu so the current page is visible.
Two levels is where plain collapse stays manageable.
A third level multiplies toggle states, indentation rules and the open-the-parents logic. That’s the point where a plugin or a template earns its weight.
Is a Bootstrap Sidebar Accessible?
Only when the markup supplies what the plugins do not. That means labels, a named landmark and a sensible focus order.
| Element | Attribute | Rule |
|---|
| Collapse toggle | aria-expanded | false when the panel starts closed, true when show opens it |
| Offcanvas panel | aria-labelledby | Points at the panel title |
| Sidebar nav | aria-label | Names the landmark among other nav regions |
| Submenu toggle | button plus aria-controls | Disclosure pattern |
The first rule comes from Bootstrap’s collapse documentation. The offcanvas docs add that the panel is conceptually a modal dialog, which is why it needs a name.
The W3C’s ARIA attributes in the Authoring Practices point sites toward a disclosure pattern for navigation. A button with aria-expanded and aria-controls shows and hides a list of links.
That example avoids the menu role on purpose. Menu and menubar roles come with keyboard interactions that assistive technologies expect, and typical site navigation does not need them.
A sidebar of plain links should not carry role="menu".
Run through the keyboard behavior by hand. Tab should reach the toggle before the links it controls, and Esc should close an open submenu and return focus to its button (the W3C example scripts this itself). Enter and Space work on button toggles with no extra code, unlike anchors with href="#".
Icon-only mode adds a trap. Labels hidden with display: none disappear for screen readers too, so hide them with visually-hidden or give each link an aria-label.
For checks beyond the sidebar, a web accessibility checklist covers contrast, forms and the rest of the page.
What Changes Between Bootstrap 4 and Bootstrap 5 Sidebars?
Bootstrap 5 dropped jQuery, renamed the data attributes to data-bs-*, added offcanvas and moved left and right utilities to start and end. Bootstrap 4 sidebar snippets need edits before they run.
| Feature | Bootstrap 4 | Bootstrap 5 |
|---|
| Toggle attributes | data-toggle, data-target | data-bs-toggle, data-bs-target |
| jQuery | Required by the plugins | Not required |
| Slide-in panel | None, custom CSS or collapse | Offcanvas component |
| Auto margins | ml-auto, mr-auto | ms-auto, me-auto |
| Screen-reader text | sr-only | visually-hidden |
Bootstrap 5 plugins run on plain JavaScript, so a sidebar toggle works without loading jQuery at all.
Not every offcanvas feature landed at once. According to Bootstrap’s migration guide, v5.0.0 dropped jQuery and added offcanvas. Navbars got offcanvas drawers in v5.1.0, and the responsive variants, .offcanvas-sm through .offcanvas-xxl, came with v5.2.0.
A sidebar built on .offcanvas-lg does nothing on 5.0 or 5.1, because the class does not exist there yet.
The old attributes fail quietly. A pasted Bootstrap 4 toggle keeps data-toggle and the Bootstrap 5 plugin ignores it, so the button simply does nothing.
Search the project for data-toggle, data-target, data-dismiss and data-parent, then add the bs- prefix to each.
For a new project there is no reason to build the Bootstrap 4 version.
When Should You Use a Sidebar Template Instead of Building One?
Use a template when the sidebar needs an icon-only folded mode, multi-level menus or saved state out of the box. Build it by hand when it’s one level of links.
| Template | Bootstrap base | Sidebar feature |
|---|
| AdminLTE v4 | Bootstrap 5.3.8 | Collapsed mode, opt-in state persistence |
| Tabler 1.5 | Bootstrap 5.3.8 inside @tabler/core | navbar-folded icon strip, 16rem default width |
| SB Admin 2 | Bootstrap 4.6.0 with jQuery | Admin dashboard shell |
Sources are AdminLTE’s repository, the Tabler 1.5 release post and the SB Admin 2 package file. Start Bootstrap’s Simple Sidebar is the minimal option, an off-canvas sidebar navigation template under the MIT license.
Templates change behavior between releases. AdminLTE first shipped sidebar persistence in localStorage, then made it opt-in through data-enable-persistence="true" and flagged that as a breaking change.
Tabler 1.5 bundles Bootstrap 5.3.8 inside its own package, so the Bootstrap version now moves with Tabler’s releases. Tabler has since shipped 1.6 and 1.7, so confirm the bundled Bootstrap version in the release you install.
A hand-built sidebar stops being worth it at menus three or more levels deep, at a folded sidebar that expands on hover, and when long menus need a styled scrollbar.
For multi-level menus, MetisMenu is a jQuery plugin for collapsible menus, with options that map onto Bootstrap 5 classes such as .nav-link. Version 3.1.0 added jQuery 4 support in January 2026 (MetisMenu release history).
It needs jQuery, so it brings back the dependency Bootstrap 5 removed.
For scrolling, SimpleBar replaces only the look of the scrollbar and keeps native overflow scrolling, according to its README. It drops onto an overflow-auto list without changing how scrolling works.
Building by hand keeps the markup and ARIA attributes yours, and Bootstrap is the only thing you ever have to upgrade. The cost is that folded mode, persistence and deep menus are yours to write.
A template hands you folded and multi-level behavior already built. In return, its release cycle can change how the sidebar behaves, and the Bootstrap version it ships can lag behind.
Sources disagree on SB Admin 2. A GitHub issue on its repository reports a live preview running Bootstrap 5.1.3 while the download ships Bootstrap 4.6.0.
Read the package file, not the preview page, before picking a template.
A full admin template is the wrong tool for a documentation site with ten links.
Bootstrap Sidebar FAQ
How do you put a Bootstrap sidebar on the right side?
Swap offcanvas-start for offcanvas-end, which Bootstrap’s docs describe as placing the panel on the right of the viewport.
For a static column, add flex-row-reverse to the wrapper.
Which icon library fits sidebar links?
Bootstrap Icons is the natural pick. Install it with npm i bootstrap-icons, then put an i element with classes like bi bi-house-fill before each label.
Font Awesome works the same way with its own classes. Mark decorative icons aria-hidden="true", as the Bootstrap Icons README does in its examples, so the text stays the link’s name.
Why does the offcanvas sidebar stay open after a link click?
By default the panel closes from its close button, a click on the backdrop or the Esc key, not from link clicks. Add data-bs-dismiss=”offcanvas” to each link, or call hide() on the instance from Offcanvas.getOrCreateInstance.
Full page loads reset the panel on their own. The problem shows up with anchor links and single-page routes.
Can a Bootstrap sidebar be built in React?
Yes. React-Bootstrap ships an Offcanvas component driven by the show, onHide and placement props, so React state replaces the data attributes.
Leave data-bs-toggle off in that setup. Two owners of the open state will fight each other.
What to Test Before a Bootstrap Sidebar Ships
Start with both layout states, side by side. Keyboard behavior in each state comes next, and the longest menu on the shortest screen goes last. Each pass assumes the one before it holds.
Layout goes first because a broken column makes every later check meaningless. Failure conditions go last because they need the working version to break.
A sidebar built on a responsive offcanvas class has two rendering modes, so every check runs twice. That doubling is the price of the pattern, and a static sidebar needs one pass.
As of the Bootstrap team’s October 8, 2026 announcement, version 5 has no end-of-life date. A stable Bootstrap 6 release would change this test list, so recheck it then.