🎉 Limited offer! Get a Pro license and save up to $1.000. 🎉 Learn more

Bootstrap scrollspy

Bootstrap scrollspy component automatically update navigation or list group components based on scroll position to indicate which link is currently active in the viewport. Learn how to use Bootstrap scrollspy.

How it works

Scrollspy has a few requirements to function properly:

  • If you’re building our JavaScript from source, it requires util.js.
  • It must be used on a Bootstrap nav component or list group.
  • Scrollspy requires position: relative; on the element you’re spying on, usually the <body>.
  • When spying on elements other than the <body>, be sure to have a height set and overflow-y: scroll; applied.
  • Anchors (<a>) are required and must point to an element with that id.

When successfully implemented, your nav or list group will update accordingly, moving the .active class from one item to the next based on their associated targets.

Example in navbar

Scroll the area below the navbar and watch the active class change. The dropdown items will be highlighted as well.

@fat

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce consequat, purus at luctus pulvinar, sapien libero scelerisque neque, sed bibendum ex dui at felis. Integer sed imperdiet nibh, non eleifend lectus. Sed interdum, tortor et rutrum elementum, nisi risus venenatis risus, eget dictum ligula lacus et magna. Nullam pharetra enim quis velit pellentesque euismod. Integer nec neque massa. Maecenas sollicitudin id justo id varius. Maecenas vel nisl eget velit aliquam facilisis. Aenean luctus placerat ornare. Cras congue dolor et enim molestie rhoncus. Proin volutpat, augue eget luctus scelerisque, orci nisi mollis eros, ut volutpat ipsum justo ac tortor.

Curabitur eget arcu quam. Nullam blandit justo eu commodo mollis. Quisque hendrerit orci vitae ante faucibus molestie. Praesent maximus et dolor eu condimentum. Praesent egestas est eu sem scelerisque tempor. Curabitur posuere metus vitae risus ultricies fermentum. Nulla fermentum, elit ac maximus laoreet, arcu massa bibendum ipsum, ac feugiat tellus orci id erat. Pellentesque elit felis, vehicula et egestas nec, pulvinar quis magna. Morbi sit amet malesuada erat, a placerat ex.

Praesent imperdiet, nulla sit amet vehicula volutpat, dolor velit aliquet mauris, a placerat orci urna vitae tellus. In hac habitasse platea dictumst. Donec ut elit eu urna tristique pellentesque. Maecenas dignissim iaculis scelerisque. Aenean ligula neque, efficitur sed elementum id, posuere eget lectus. Sed tristique sollicitudin arcu at interdum. Donec eget gravida nisi, id mollis nibh. Aliquam id accumsan quam. Praesent at suscipit magna. Sed porttitor tincidunt congue. Fusce dignissim dapibus consectetur. Ut bibendum finibus sem eu sodales. Nullam porta nisi lacus, at mollis arcu malesuada at.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce consequat, purus at luctus pulvinar, sapien libero scelerisque neque, sed bibendum ex dui at felis. Integer sed imperdiet nibh, non eleifend lectus. Sed interdum, tortor et rutrum elementum, nisi risus venenatis risus, eget dictum ligula lacus et magna. Nullam pharetra enim quis velit pellentesque euismod. Integer nec neque massa. Maecenas sollicitudin id justo id varius. Maecenas vel nisl eget velit aliquam facilisis. Aenean luctus placerat ornare. Cras congue dolor et enim molestie rhoncus. Proin volutpat, augue eget luctus scelerisque, orci nisi mollis eros, ut volutpat ipsum justo ac tortor.

Curabitur eget arcu quam. Nullam blandit justo eu commodo mollis. Quisque hendrerit orci vitae ante faucibus molestie. Praesent maximus et dolor eu condimentum. Praesent egestas est eu sem scelerisque tempor. Curabitur posuere metus vitae risus ultricies fermentum. Nulla fermentum, elit ac maximus laoreet, arcu massa bibendum ipsum, ac feugiat tellus orci id erat. Pellentesque elit felis, vehicula et egestas nec, pulvinar quis magna. Morbi sit amet malesuada erat, a placerat ex.

Praesent imperdiet, nulla sit amet vehicula volutpat, dolor velit aliquet mauris, a placerat orci urna vitae tellus. In hac habitasse platea dictumst. Donec ut elit eu urna tristique pellentesque. Maecenas dignissim iaculis scelerisque. Aenean ligula neque, efficitur sed elementum id, posuere eget lectus. Sed tristique sollicitudin arcu at interdum. Donec eget gravida nisi, id mollis nibh. Aliquam id accumsan quam. Praesent at suscipit magna. Sed porttitor tincidunt congue. Fusce dignissim dapibus consectetur. Ut bibendum finibus sem eu sodales. Nullam porta nisi lacus, at mollis arcu malesuada at.

</p>
<nav id="navbar-example2" class="navbar navbar-light bg-light">
  <a class="navbar-brand" href="#">Navbar</a>
  <ul class="nav nav-pills">
    <li class="nav-item">
      <a class="nav-link" href="#fat">@fat</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#mdo">@mdo</a>
    </li>
    <li class="nav-item dropdown">
      <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">Dropdown</a>
      <div class="dropdown-menu">
        <a class="dropdown-item" href="#one">one</a>
        <a class="dropdown-item" href="#two">two</a>
        <div role="separator" class="dropdown-divider"></div>
        <a class="dropdown-item" href="#three">three</a>
      </div>
    </li>
  </ul>
</nav>
<div data-spy="scroll" data-target="#navbar-example2" data-offset="0">
  <h4 id="fat">@fat</h4>
  <p>...</p>
  <h4 id="mdo">@mdo</h4>
  <p>...</p>
  <h4 id="one">one</h4>
  <p>...</p>
  <h4 id="two">two</h4>
  <p>...</p>
  <h4 id="three">three</h4>
  <p>...</p>
</div>

Example with nested nav

Scrollspy also works with nested .navs. If a nested .nav is .active, its parents will also be .active. Scroll the area next to the navbar and watch the active class change.

Item 1

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce consequat, purus at luctus pulvinar, sapien libero scelerisque neque, sed bibendum ex dui at felis. Integer sed imperdiet nibh, non eleifend lectus. Sed interdum, tortor et rutrum elementum, nisi risus venenatis risus, eget dictum ligula lacus et magna. Nullam pharetra enim quis velit pellentesque euismod. Integer nec neque massa. Maecenas sollicitudin id justo id varius. Maecenas vel nisl eget velit aliquam facilisis. Aenean luctus placerat ornare. Cras congue dolor et enim molestie rhoncus. Proin volutpat, augue eget luctus scelerisque, orci nisi mollis eros, ut volutpat ipsum justo ac tortor.

Curabitur eget arcu quam. Nullam blandit justo eu commodo mollis. Quisque hendrerit orci vitae ante faucibus molestie. Praesent maximus et dolor eu condimentum. Praesent egestas est eu sem scelerisque tempor. Curabitur posuere metus vitae risus ultricies fermentum. Nulla fermentum, elit ac maximus laoreet, arcu massa bibendum ipsum, ac feugiat tellus orci id erat. Pellentesque elit felis, vehicula et egestas nec, pulvinar quis magna. Morbi sit amet malesuada erat, a placerat ex.

Praesent imperdiet, nulla sit amet vehicula volutpat, dolor velit aliquet mauris, a placerat orci urna vitae tellus. In hac habitasse platea dictumst. Donec ut elit eu urna tristique pellentesque. Maecenas dignissim iaculis scelerisque. Aenean ligula neque, efficitur sed elementum id, posuere eget lectus. Sed tristique sollicitudin arcu at interdum. Donec eget gravida nisi, id mollis nibh. Aliquam id accumsan quam. Praesent at suscipit magna. Sed porttitor tincidunt congue. Fusce dignissim dapibus consectetur. Ut bibendum finibus sem eu sodales. Nullam porta nisi lacus, at mollis arcu malesuada at.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce consequat, purus at luctus pulvinar, sapien libero scelerisque neque, sed bibendum ex dui at felis. Integer sed imperdiet nibh, non eleifend lectus. Sed interdum, tortor et rutrum elementum, nisi risus venenatis risus, eget dictum ligula lacus et magna. Nullam pharetra enim quis velit pellentesque euismod. Integer nec neque massa. Maecenas sollicitudin id justo id varius. Maecenas vel nisl eget velit aliquam facilisis. Aenean luctus placerat ornare. Cras congue dolor et enim molestie rhoncus. Proin volutpat, augue eget luctus scelerisque, orci nisi mollis eros, ut volutpat ipsum justo ac tortor.

Curabitur eget arcu quam. Nullam blandit justo eu commodo mollis. Quisque hendrerit orci vitae ante faucibus molestie. Praesent maximus et dolor eu condimentum. Praesent egestas est eu sem scelerisque tempor. Curabitur posuere metus vitae risus ultricies fermentum. Nulla fermentum, elit ac maximus laoreet, arcu massa bibendum ipsum, ac feugiat tellus orci id erat. Pellentesque elit felis, vehicula et egestas nec, pulvinar quis magna. Morbi sit amet malesuada erat, a placerat ex.

Praesent imperdiet, nulla sit amet vehicula volutpat, dolor velit aliquet mauris, a placerat orci urna vitae tellus. In hac habitasse platea dictumst. Donec ut elit eu urna tristique pellentesque. Maecenas dignissim iaculis scelerisque. Aenean ligula neque, efficitur sed elementum id, posuere eget lectus. Sed tristique sollicitudin arcu at interdum. Donec eget gravida nisi, id mollis nibh. Aliquam id accumsan quam. Praesent at suscipit magna. Sed porttitor tincidunt congue. Fusce dignissim dapibus consectetur. Ut bibendum finibus sem eu sodales. Nullam porta nisi lacus, at mollis arcu malesuada at.

<nav id="navbar-example3" class="navbar navbar-light bg-light">
  <a class="navbar-brand" href="#">Navbar</a>
  <nav class="nav nav-pills flex-column">
    <a class="nav-link" href="#item-1">Item 1</a>
    <nav class="nav nav-pills flex-column">
      <a class="nav-link ml-3 my-1" href="#item-1-1">Item 1-1</a>
      <a class="nav-link ml-3 my-1" href="#item-1-2">Item 1-2</a>
    </nav>
    <a class="nav-link" href="#item-2">Item2</a>
    <a class="nav-link" href="#item-3">Item3</a>
    <nav class="nav nav-pills flex-column">
      <a class="nav-link ml-3 my-1" href="#item-3-1">Item 3-1</a>
      <a class="nav-link ml-3 my-1" href="#item-3-2">Item 3-2</a>
    </nav>
  </nav>
</nav>

<div data-spy="scroll" data-target="#navbar-example3" data-offset="0">
  <h4 id="item-1">Item 1</h4>
  <p>...</p>
  <h5 id="item-1-1">Item 1-1</h5>
  <p>...</p>
  <h5 id="item-1-2">Item 2-2</h5>
  <p>...</p>
  <h4 id="item-2">Item 2</h4>
  <p>...</p>
  <h4 id="item-3">Item 3</h4>
  <p>...</p>
  <h5 id="item-3-1">Item 3-1</h5>
  <p>...</p>
  <h5 id="item-3-2">Item 3-2</h5>
  <p>...</p>
</div>

Example with list-group

Scrollspy also works with .list-groups. Scroll the area next to the list group and watch the active class change.

Item 1

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce consequat, purus at luctus pulvinar, sapien libero scelerisque neque, sed bibendum ex dui at felis. Integer sed imperdiet nibh, non eleifend lectus. Sed interdum, tortor et rutrum elementum, nisi risus venenatis risus, eget dictum ligula lacus et magna. Nullam pharetra enim quis velit pellentesque euismod. Integer nec neque massa. Maecenas sollicitudin id justo id varius. Maecenas vel nisl eget velit aliquam facilisis. Aenean luctus placerat ornare. Cras congue dolor et enim molestie rhoncus. Proin volutpat, augue eget luctus scelerisque, orci nisi mollis eros, ut volutpat ipsum justo ac tortor.

Curabitur eget arcu quam. Nullam blandit justo eu commodo mollis. Quisque hendrerit orci vitae ante faucibus molestie. Praesent maximus et dolor eu condimentum. Praesent egestas est eu sem scelerisque tempor. Curabitur posuere metus vitae risus ultricies fermentum. Nulla fermentum, elit ac maximus laoreet, arcu massa bibendum ipsum, ac feugiat tellus orci id erat. Pellentesque elit felis, vehicula et egestas nec, pulvinar quis magna. Morbi sit amet malesuada erat, a placerat ex.

Praesent imperdiet, nulla sit amet vehicula volutpat, dolor velit aliquet mauris, a placerat orci urna vitae tellus. In hac habitasse platea dictumst. Donec ut elit eu urna tristique pellentesque. Maecenas dignissim iaculis scelerisque. Aenean ligula neque, efficitur sed elementum id, posuere eget lectus. Sed tristique sollicitudin arcu at interdum. Donec eget gravida nisi, id mollis nibh. Aliquam id accumsan quam. Praesent at suscipit magna. Sed porttitor tincidunt congue. Fusce dignissim dapibus consectetur. Ut bibendum finibus sem eu sodales. Nullam porta nisi lacus, at mollis arcu malesuada at.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce consequat, purus at luctus pulvinar, sapien libero scelerisque neque, sed bibendum ex dui at felis. Integer sed imperdiet nibh, non eleifend lectus. Sed interdum, tortor et rutrum elementum, nisi risus venenatis risus, eget dictum ligula lacus et magna. Nullam pharetra enim quis velit pellentesque euismod. Integer nec neque massa. Maecenas sollicitudin id justo id varius. Maecenas vel nisl eget velit aliquam facilisis. Aenean luctus placerat ornare. Cras congue dolor et enim molestie rhoncus. Proin volutpat, augue eget luctus scelerisque, orci nisi mollis eros, ut volutpat ipsum justo ac tortor.

Curabitur eget arcu quam. Nullam blandit justo eu commodo mollis. Quisque hendrerit orci vitae ante faucibus molestie. Praesent maximus et dolor eu condimentum. Praesent egestas est eu sem scelerisque tempor. Curabitur posuere metus vitae risus ultricies fermentum. Nulla fermentum, elit ac maximus laoreet, arcu massa bibendum ipsum, ac feugiat tellus orci id erat. Pellentesque elit felis, vehicula et egestas nec, pulvinar quis magna. Morbi sit amet malesuada erat, a placerat ex.

Praesent imperdiet, nulla sit amet vehicula volutpat, dolor velit aliquet mauris, a placerat orci urna vitae tellus. In hac habitasse platea dictumst. Donec ut elit eu urna tristique pellentesque. Maecenas dignissim iaculis scelerisque. Aenean ligula neque, efficitur sed elementum id, posuere eget lectus. Sed tristique sollicitudin arcu at interdum. Donec eget gravida nisi, id mollis nibh. Aliquam id accumsan quam. Praesent at suscipit magna. Sed porttitor tincidunt congue. Fusce dignissim dapibus consectetur. Ut bibendum finibus sem eu sodales. Nullam porta nisi lacus, at mollis arcu malesuada at.

<div id="list-example" class="list-group">
  <a class="list-group-item list-group-item-action" href="#list-item-1">Item 1</a>
  <a class="list-group-item list-group-item-action" href="#list-item-2">Item2</a>
  <a class="list-group-item list-group-item-action" href="#list-item-3">Item 3</a>
  <a class="list-group-item list-group-item-action" href="#list-item-4">Item 4</a>
</div>
<div data-spy="scroll" data-target="#list-example" data-offset="0" class="scrollspy-example">
  <h4 id="list-item-1">Item 1</h4>
  <p>...</p>
  <h4 id="list-item-2">Item 2</h4>
  <p>...</p>
  <h4 id="list-item-3">Item 3</h4>
  <p>...</p>
  <h4 id="list-item-4">Item 4</h4>
  <p>...</p>
</div>

Usage

Via data attributes

To easily add scrollspy behavior to your topbar navigation, add data-spy="scroll" to the element you want to spy on (most typically this would be the <body>). Then add the data-target attribute with the ID or class of the parent element of any Bootstrap .nav component.

body {
  position: relative;
}
<body data-spy="scroll" data-target="#navbar-example">
  ...
  <div id="navbar-example">
    <ul class="nav nav-tabs" role="tablist">
      ...
    </ul>
  </div>
  ...
</body>

Via JavaScript

After adding position: relative; in your CSS, call the scrollspy via JavaScript:

$('body').scrollspy({ target: '#navbar-example' })

Resolvable ID targets required

Navbar links must have resolvable id targets. For example, a <a href="#home">home</a> must correspond to something in the DOM like <div id="home"></div>.

Non-:visible target elements ignored

Target elements that are not :visible according to jQuery will be ignored and their corresponding nav items will never be highlighted.

Methods

.scrollspy('refresh')

When using scrollspy in conjunction with adding or removing of elements from the DOM, you’ll need to call the refresh method like so:

$('[data-spy="scroll"]').each(function () {
  var $spy = $(this).scrollspy('refresh')
})

.scrollspy('dispose')

Destroys an element’s scrollspy.

Options

Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in data-offset="".

Name Type Default Description
offset number 10 Pixels to offset from top when calculating position of scroll.

Events

Event Type Description
activate.bs.scrollspy This event fires on the scroll element whenever a new item becomes activated by the scrollspy.
$('[data-spy="scroll"]').on('activate.bs.scrollspy', function () {
  // do something…
})