A navbar that stays visible as users scroll is one of the most common requirements in web development. Bootstrap 5 gives you a few ways to do it, each with different tradeoffs.
Method 1: sticky-top (Recommended)
The simplest approach. Add sticky-top to your navbar element:
<nav class="navbar navbar-expand-lg bg-white border-bottom shadow-sm sticky-top">
<div class="container-fluid">
<a class="navbar-brand fw-bold" href="#" style="color:#fd4766;">BootstrapPlanet</a>
<button class="navbar-toggler" type="button"
data-bs-toggle="collapse" data-bs-target="#navMenu">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navMenu">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link active" href="#">Home</a></li>
<li class="nav-item"><a class="nav-link" href="#">Components</a></li>
<li class="nav-item"><a class="nav-link" href="#">Tutorials</a></li>
</ul>
<a href="https://lettstartdesign.com"
class="btn btn-sm text-white px-3" style="background:#fd4766;">
Templates
</a>
</div>
</div>
</nav>
<!-- Page content follows directly — no padding needed -->
<main class="container py-4">
<h1>Page Content</h1>
<p>The navbar sticks to the top when you scroll past it.</p>
</main>
Why this is better than fixed-top for most cases:
- No body padding required
- Stays in document flow
- Content isn't hidden underneath it
- Works out of the box with no JavaScript
The one catch: if any parent element has overflow: hidden or overflow: auto, sticky positioning breaks. Check your layout wrappers if it stops working.
Method 2: fixed-top
Use fixed-top when you need the navbar absolutely always visible — even before the user scrolls past it:
<!-- Add padding to body to prevent content hiding under the fixed navbar -->
<style>
body { padding-top: 56px; }
</style>
<nav class="navbar navbar-expand-lg bg-white border-bottom shadow-sm fixed-top">
<div class="container-fluid">
<a class="navbar-brand fw-bold" href="#" style="color:#fd4766;">BootstrapPlanet</a>
<!-- rest of navbar -->
</div>
</nav>
<main class="container py-4">
<!-- content starts below the fixed navbar -->
</main>
For dynamic navbar heights — when you're not sure of the exact pixel value:
// Set body padding equal to actual navbar height
const navbar = document.querySelector('.navbar')
document.body.style.paddingTop = navbar.offsetHeight + 'px'
// Update on resize
window.addEventListener('resize', () => {
document.body.style.paddingTop = navbar.offsetHeight + 'px'
})
Method 3: Shrink on Scroll
A navbar that has larger padding at the top of the page and shrinks to a tighter layout once you scroll — popular on marketing sites:
<style>
.navbar-shrink {
transition: padding 0.3s ease, box-shadow 0.3s ease;
padding-top: 16px;
padding-bottom: 16px;
}
.navbar-shrink.scrolled {
padding-top: 8px;
padding-bottom: 8px;
box-shadow: 0 2px 16px rgba(0,0,0,0.1) !important;
}
</style>
<nav class="navbar navbar-expand-lg bg-white sticky-top navbar-shrink" id="mainNav">
<div class="container-fluid">
<a class="navbar-brand fw-bold fs-5" href="#" style="color:#fd4766;">BootstrapPlanet</a>
<button class="navbar-toggler" type="button"
data-bs-toggle="collapse" data-bs-target="#shrinkMenu">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="shrinkMenu">
<ul class="navbar-nav me-auto">
<li class="nav-item"><a class="nav-link" href="#">Home</a></li>
<li class="nav-item"><a class="nav-link" href="#">Components</a></li>
<li class="nav-item"><a class="nav-link" href="#">Tutorials</a></li>
</ul>
<a href="https://lettstartdesign.com"
class="btn btn-sm text-white px-3" style="background:#fd4766;">
Templates
</a>
</div>
</div>
</nav>
<script>
window.addEventListener('scroll', function () {
const nav = document.getElementById('mainNav')
if (window.scrollY > 50) {
nav.classList.add('scrolled')
} else {
nav.classList.remove('scrolled')
}
})
</script>
Method 4: Auto-Hide on Scroll Down, Show on Scroll Up
The navbar disappears when scrolling down (giving more screen space) and reappears when scrolling up — great for content-heavy pages:
<style>
.navbar-autohide {
position: sticky;
top: 0;
z-index: 1030;
transition: top 0.3s ease;
}
.navbar-autohide.hidden {
top: -80px; /* push above viewport */
}
</style>
<nav class="navbar navbar-expand-lg bg-white border-bottom navbar-autohide" id="autoNav">
<div class="container-fluid">
<a class="navbar-brand fw-bold" href="#" style="color:#fd4766;">BootstrapPlanet</a>
<div class="d-flex gap-3">
<a class="nav-link text-muted" href="#">Components</a>
<a class="nav-link text-muted" href="#">Tutorials</a>
<a href="https://lettstartdesign.com"
class="btn btn-sm text-white px-3" style="background:#fd4766;">
Templates
</a>
</div>
</div>
</nav>
<script>
let lastScrollY = 0
window.addEventListener('scroll', function () {
const nav = document.getElementById('autoNav')
const currentScrollY = window.scrollY
if (currentScrollY > lastScrollY && currentScrollY > 80) {
// Scrolling down — hide navbar
nav.classList.add('hidden')
} else {
// Scrolling up — show navbar
nav.classList.remove('hidden')
}
lastScrollY = currentScrollY
})
</script>
Which Method to Use
| Scenario | Use |
|---|---|
| Standard site, simplest setup | sticky-top |
| Always visible from page load | fixed-top + body padding |
| Marketing/landing page with large hero | Shrink on scroll |
| Content-heavy article or blog | Auto-hide on scroll down |
| Admin dashboard | sticky-top — keeps it simple |
For the Angular + Bootstrap admin dashboards I build, sticky-top on the top header combined with a separate fixed sidebar is the cleanest pattern. No JavaScript needed for the navbar itself. If you want a production-ready example, the Marvel Angular Dashboard uses exactly this approach — 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.