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

ScenarioUse
Standard site, simplest setupsticky-top
Always visible from page loadfixed-top + body padding
Marketing/landing page with large heroShrink on scroll
Content-heavy article or blogAuto-hide on scroll down
Admin dashboardsticky-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

sticky-top uses CSS position:sticky — the navbar scrolls with the page until it reaches the top, then sticks. It stays in document flow so no body padding needed. fixed-top uses position:fixed — always visible at the top regardless of scroll, but removed from document flow, requiring padding-top on body equal to navbar height (~56px).
The most common cause is a parent element with overflow:hidden or overflow:auto — this breaks CSS sticky positioning. Check all parent elements. Another cause is the parent not being tall enough to scroll. sticky-top only sticks when there's overflow to scroll past.
The default Bootstrap navbar height is approximately 56px. Add padding-top:56px to body. For accuracy use JavaScript: document.body.style.paddingTop = document.querySelector('.navbar').offsetHeight + 'px'. If you've customised navbar padding the height will differ.
Listen to the window scroll event. When scrollY exceeds a threshold (e.g. 50px), add a class to the navbar that reduces padding and adds a shadow via CSS transition. When scrollY returns below the threshold, remove the class.

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.

Related Components