Bootstrap 5 doesn't ship a sidebar component — you build it yourself with CSS flexbox. The good news is it's straightforward once you understand the three-part structure: wrapper → sidebar → main content.
The Core Layout Structure
Every sidebar layout follows this pattern:
<div class="wrapper d-flex"> <!-- flex container -->
<aside class="sidebar"> <!-- fixed width -->
<!-- navigation -->
</aside>
<div class="main-content flex-grow-1"> <!-- fills remaining space -->
<!-- page content -->
</div>
</div>
1. Basic Sticky Sidebar
A sidebar that sticks while the main content scrolls:
<style>
body { margin: 0; }
.sidebar {
width: 240px;
min-height: 100vh;
background: #fff;
border-right: 1px solid #e5e7eb;
position: sticky;
top: 0;
height: 100vh;
overflow-y: auto;
flex-shrink: 0;
display: flex;
flex-direction: column;
}
.sidebar-brand {
padding: 16px 20px;
border-bottom: 1px solid #e5e7eb;
font-weight: 700;
color: #fd4766;
font-size: 1rem;
}
.sidebar-nav {
padding: 8px;
flex: 1;
}
.sidebar-link {
display: flex;
align-items: center;
gap: 10px;
padding: 9px 12px;
border-radius: 6px;
text-decoration: none;
color: #6b7280;
font-size: 0.88rem;
margin-bottom: 2px;
transition: background 0.15s, color 0.15s;
}
.sidebar-link:hover { background: #f3f4f6; color: #111; }
.sidebar-link.active { background: rgba(253,71,102,0.08); color: #fd4766; font-weight: 600; }
.sidebar-footer {
padding: 12px 16px;
border-top: 1px solid #e5e7eb;
}
.main-content {
flex: 1;
min-width: 0;
background: #f8f9fa;
min-height: 100vh;
}
.main-header {
background: #fff;
border-bottom: 1px solid #e5e7eb;
padding: 12px 24px;
position: sticky;
top: 0;
z-index: 10;
}
</style>
<div class="d-flex">
<!-- Sidebar -->
<aside class="sidebar">
<div class="sidebar-brand">AdminPanel</div>
<nav class="sidebar-nav">
<div class="text-uppercase px-2 mb-1"
style="font-size:0.65rem;color:#9ca3af;letter-spacing:0.08em;font-weight:600;">
Main
</div>
<a href="#" class="sidebar-link active">🏠 Dashboard</a>
<a href="#" class="sidebar-link">
📦 Templates
<span class="badge ms-auto" style="background:#fd4766;font-size:0.62rem;">12</span>
</a>
<a href="#" class="sidebar-link">👥 Customers</a>
<a href="#" class="sidebar-link">📊 Analytics</a>
<div class="text-uppercase px-2 mb-1 mt-3"
style="font-size:0.65rem;color:#9ca3af;letter-spacing:0.08em;font-weight:600;">
Settings
</div>
<a href="#" class="sidebar-link">⚙️ Settings</a>
<a href="#" class="sidebar-link">❓ Help</a>
</nav>
<div class="sidebar-footer">
<div class="d-flex align-items-center gap-2">
<div class="rounded-circle text-white d-flex align-items-center justify-content-center fw-bold"
style="width:32px;height:32px;background:#fd4766;font-size:0.72rem;flex-shrink:0;">GS</div>
<div>
<p class="fw-semibold mb-0" style="font-size:0.82rem;">Gagan Singh</p>
<p class="text-muted mb-0" style="font-size:0.7rem;">Founder</p>
</div>
</div>
</div>
</aside>
<!-- Main content -->
<div class="main-content">
<div class="main-header d-flex align-items-center justify-content-between">
<h6 class="fw-bold mb-0">Dashboard</h6>
<a href="https://lettstartdesign.com"
class="btn btn-sm text-white px-3" style="background:#fd4766;">
Templates
</a>
</div>
<div class="p-4">
<p class="text-muted">Main content area. The sidebar stays fixed while this scrolls.</p>
</div>
</div>
</div>
2. Collapsible Sidebar
Add a toggle button that narrows the sidebar to icon-only mode:
<style>
.sidebar-collapsible {
width: 240px;
transition: width 0.3s ease;
overflow: hidden;
flex-shrink: 0;
}
.sidebar-collapsible.collapsed { width: 64px; }
.sidebar-collapsible .label {
transition: opacity 0.2s;
white-space: nowrap;
overflow: hidden;
}
.sidebar-collapsible.collapsed .label { opacity: 0; width: 0; }
.toggle-btn {
background: none;
border: 1px solid #e5e7eb;
border-radius: 50%;
width: 24px; height: 24px;
cursor: pointer;
font-size: 0.7rem;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
right: -12px;
top: 20px;
background: #fff;
z-index: 10;
}
</style>
<div class="d-flex" style="position:relative;">
<aside class="sidebar-collapsible bg-white border-end" id="collSidebar"
style="min-height:100vh;position:relative;">
<button class="toggle-btn" id="toggleBtn"
onclick="toggleSidebar()">◀</button>
<div class="px-3 py-3 border-bottom" style="min-height:56px;">
<div class="d-flex align-items-center gap-2">
<div class="rounded text-white d-flex align-items-center justify-content-center fw-bold flex-shrink-0"
style="width:28px;height:28px;background:#fd4766;font-size:0.72rem;">AP</div>
<span class="fw-bold label" style="color:#fd4766;">AdminPanel</span>
</div>
</div>
<nav class="py-2 px-2">
<a href="#" class="d-flex align-items-center gap-2 px-2 py-2 rounded text-decoration-none mb-1"
style="color:#fd4766;background:rgba(253,71,102,0.08);">
<span class="flex-shrink-0">🏠</span>
<span class="label">Dashboard</span>
</a>
<a href="#" class="d-flex align-items-center gap-2 px-2 py-2 rounded text-decoration-none mb-1 text-muted">
<span class="flex-shrink-0">📦</span>
<span class="label">Templates</span>
</a>
<a href="#" class="d-flex align-items-center gap-2 px-2 py-2 rounded text-decoration-none mb-1 text-muted">
<span class="flex-shrink-0">👥</span>
<span class="label">Customers</span>
</a>
<a href="#" class="d-flex align-items-center gap-2 px-2 py-2 rounded text-decoration-none mb-1 text-muted">
<span class="flex-shrink-0">📊</span>
<span class="label">Analytics</span>
</a>
</nav>
</aside>
<div class="flex-grow-1 p-4" style="background:#f8f9fa;min-height:100vh;">
<p class="text-muted">Click the arrow button to collapse the sidebar.</p>
</div>
</div>
<script>
let collapsed = false
function toggleSidebar() {
collapsed = !collapsed
const sidebar = document.getElementById('collSidebar')
const btn = document.getElementById('toggleBtn')
sidebar.classList.toggle('collapsed', collapsed)
btn.textContent = collapsed ? '▶' : '◀'
}
</script>
3. Responsive: Desktop Sidebar + Mobile Off-Canvas
The production-ready pattern — desktop sidebar plus Bootstrap off-canvas for mobile:
<div class="d-flex">
<!-- Desktop sidebar: hidden on mobile -->
<aside class="d-none d-lg-flex flex-column bg-white border-end"
style="width:240px;min-height:100vh;position:sticky;top:0;height:100vh;overflow-y:auto;flex-shrink:0;">
<div class="px-4 py-3 border-bottom fw-bold" style="color:#fd4766;">AdminPanel</div>
<nav class="p-2 flex-grow-1">
<a href="#" class="d-flex align-items-center gap-2 p-2 rounded text-decoration-none mb-1"
style="color:#fd4766;background:rgba(253,71,102,0.08);font-size:0.88rem;">
🏠 Dashboard
</a>
<a href="#" class="d-flex align-items-center gap-2 p-2 rounded text-decoration-none mb-1 text-muted"
style="font-size:0.88rem;">📦 Templates</a>
<a href="#" class="d-flex align-items-center gap-2 p-2 rounded text-decoration-none mb-1 text-muted"
style="font-size:0.88rem;">👥 Customers</a>
</nav>
</aside>
<!-- Main area -->
<div class="flex-grow-1" style="min-width:0;">
<!-- Mobile header with hamburger -->
<header class="d-lg-none bg-white border-bottom px-3 py-2 d-flex align-items-center gap-3">
<button class="btn btn-sm btn-outline-secondary border-0"
data-bs-toggle="offcanvas" data-bs-target="#mobileSidebar">☰</button>
<span class="fw-bold" style="color:#fd4766;">AdminPanel</span>
</header>
<!-- Page content -->
<main class="p-4" style="background:#f8f9fa;min-height:100vh;">
<h5 class="fw-bold mb-3">Dashboard</h5>
<p class="text-muted">Resize to mobile to see the off-canvas sidebar.</p>
</main>
</div>
</div>
<!-- Mobile off-canvas sidebar -->
<div class="offcanvas offcanvas-start" tabindex="-1" id="mobileSidebar" style="width:240px;">
<div class="offcanvas-header border-bottom">
<span class="fw-bold" style="color:#fd4766;">AdminPanel</span>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body p-2">
<a href="#" class="d-flex align-items-center gap-2 p-2 rounded text-decoration-none mb-1"
style="color:#fd4766;background:rgba(253,71,102,0.08);font-size:0.88rem;">
🏠 Dashboard
</a>
<a href="#" class="d-flex align-items-center gap-2 p-2 rounded text-decoration-none mb-1 text-muted"
style="font-size:0.88rem;">📦 Templates</a>
<a href="#" class="d-flex align-items-center gap-2 p-2 rounded text-decoration-none mb-1 text-muted"
style="font-size:0.88rem;">👥 Customers</a>
</div>
</div>
Active Link Highlighting
Add active state with a small JavaScript snippet:
// Highlight current page link
const currentPath = window.location.pathname
document.querySelectorAll('.sidebar-link').forEach(link => {
if (link.getAttribute('href') === currentPath) {
link.classList.add('active')
}
})
Or with data attributes to make it explicit:
<a href="/dashboard" class="sidebar-link" data-path="/dashboard">Dashboard</a>
const path = window.location.pathname
document.querySelectorAll('[data-path]').forEach(el => {
if (el.dataset.path === path) el.classList.add('active')
})
Dark Sidebar Variant
Swap the sidebar colors for a dark theme:
.sidebar-dark {
background: #0d0d0d;
border-right-color: #1e1e2e;
}
.sidebar-dark .sidebar-link { color: #888; }
.sidebar-dark .sidebar-link:hover { background: #1a1a2e; color: #fff; }
.sidebar-dark .sidebar-link.active { background: rgba(253,71,102,0.15); color: #fd4766; }
If you want a production-ready Angular + Bootstrap admin dashboard with a polished sidebar already built, check out the Marvel Angular Dashboard — use code FIRST30 for 30% off.
Frequently Asked Questions
Need a Full Bootstrap 5 Admin Dashboard?
Get a complete Angular 21 + Bootstrap 5 dashboard with 50+ components — built by the same team behind BootstrapPlanet.
Browse Templates →Use code FIRST30 for 30% off your first purchase.