Scrollspy

Bootstrap 5 Scrollspy component

Automatically update Bootstrap navigation or list group components based on scroll position to indicate which link is currently active in the viewport.

Note: Read the API tab to find all available options and advanced customization

Required ES init: Scrollspy *
* UMD autoinits are enabled by default. This means that you don't need to initialize the component manually. However if you are using MDBootstrap ES format then you should pass the required components to the initMDB method.

Basic example

Section 1

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Section 2

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Section 3

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Subsection A

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Subsection B

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Section 4

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

        
            
          <div class="row">
            <div class="col-md-8">
              <!-- Spied element -->
              <div
                data-mdb-scrollspy-init
                data-mdb-target="#scrollspy1"
                data-mdb-offset="0"
                class="scrollspy-example"
              >
                <section id="example-1">
                  <h3>Section 1</h3>
                  ...
                </section>
                <section id="example-2">
                  <h3>Section 2</h3>
                  ...
                </section>
                <section id="example-3">
                  <h3>Section 3</h3>
                  ...
                  <section id="example-sub-A">
                    <h3>Subsection A</h3>
                    ...
                  </section>
                  <section id="example-sub-B">
                    <h3>Subsection B</h3>
                    ...
                  </section>
                </section>
                <section id="example-4">
                  <h3>Section 4</h3>
                  ...
                </section>
              </div>
              <!-- Spied element -->
            </div>

            <div class="col-md-4">
              <!-- Scrollspy -->
              <div id="scrollspy1" class="sticky-top">
                <ul class="nav flex-column nav-pills menu-sidebar">
                  <li class="nav-item">
                    <a class="nav-link" href="#example-1">Section 1</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="#example-2">Section 2</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="#example-3">Section 3</a>
                    <ul class="nav flex-column ps-3">
                      <li class="nav-item">
                        <a class="nav-link" href="#example-sub-A">Subsection A</a>
                      </li>
                      <li class="nav-item">
                        <a class="nav-link" href="#example-sub-B">Subsection B</a>
                      </li>
                    </ul>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="#example-4">Section 4</a>
                  </li>
                </ul>
              </div>
              <!-- Scrollspy -->
            </div>
          </div>
        
        
    
        
            
          /* Styles required only for the example above */
          .scrollspy-example {
            position: relative;
            height: 200px;
            overflow: auto;
          }
        
        
    
        
            
          // Initialization for ES Users
          import { Scrollspy, initMDB } from "mdb-ui-kit";

          initMDB({ Scrollspy });
        
        
    

Collapsible

Hides all subsections of unactive section. To use it, simply add .collapsible-scrollspy class to the <a> element of section you want to set to be collapsible.

Section 1

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Section 2

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Section 3

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Subsection A

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Subsection B

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Section 4

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Labore earum natus vel minima quod error maxime, molestias ut. Fuga dignissimos nisi nemo necessitatibus quisquam obcaecati et reiciendis quaerat accusamus numquam.

        
            
          <div class="row">
            <div class="col-md-8">
              <!-- Spied element -->
              <div
                data-mdb-scrollspy-init
                data-mdb-target="#scrollspy-collapsible"
                data-mdb-offset="0"
                class="scrollspy-example"
              >
                <section id="example-1-collapsible">
                  <h3>Section 1</h3>
                  ...
                </section>
                <section id="example-2-collapsible">
                  <h3>Section 2</h3>
                  ...
                </section>
                <section id="example-3-collapsible">
                  <h3>Section 3</h3>
                  ...
                  <section id="example-sub-A-collapsible">
                    <h3>Subsection A</h3>
                    ...
                  </section>
                  <section id="example-sub-B-collapsible">
                    <h3>Subsection B</h3>
                    ...
                  </section>
                </section>
                <section id="example-4-collapsible">
                  <h3>Section 4</h3>
                  ...
                </section>
              </div>
              <!-- Spied element -->
            </div>

            <div class="col-md-4">
              <!-- Scrollspy -->
              <div id="scrollspy-collapsible" class="sticky-top">
                <ul class="nav flex-column nav-pills menu-sidebar">
                  <li class="nav-item">
                    <a class="nav-link" href="#example-1-collapsible">Section 1</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="#example-2-collapsible">Section 2</a>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link collapsible-scrollspy" href="#example-3-collapsible">Section 3</a>
                    <ul class="nav flex-column ps-3">
                      <li class="nav-item">
                        <a class="nav-link" href="#example-sub-A-collapsible">Subsection A</a>
                      </li>
                      <li class="nav-item">
                        <a class="nav-link" href="#example-sub-B-collapsible">Subsection B</a>
                      </li>
                    </ul>
                  </li>
                  <li class="nav-item">
                    <a class="nav-link" href="#example-4-collapsible">Section 4</a>
                  </li>
                </ul>
              </div>
              <!-- Scrollspy -->
            </div>
          </div>
        
        
    
        
            
          /* Styles required only for the example above */
          .scrollspy-example-collapsible {
            position: relative;
            height: 200px;
            overflow: auto;
          }
        
        
    
        
            
          // Initialization for ES Users
          import { Scrollspy, initMDB } from "mdb-ui-kit";

          initMDB({ Scrollspy });
        
        
    

How it works

Scrollspy has a few requirements to function properly:

  • 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.


Scrollspy - API


Import

Importing components depends on how your application works. If you intend to use the MDBootstrap ES format, you must first import the component and then initialize it with the initMDB method. If you are going to use the UMD format, just import the mdb-ui-kit package.

        
            
          import { Scrollspy, initMDB } from "mdb-ui-kit";
  
          initMDB({ Scrollspy });
        
        
    
        
            
          import 'mdb-ui-kit';
        
        
    

Usage

Via data attributes

Using the Scrollspy component doesn't require any additional JavaScript code - simply add data-mdb-scrollspy-init attribute to the element you’re spying on (most typically this would be the <body>) and use other data attributes to set all options. For ES format, you must first import and call the initMDB method.

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

Via JavaScript

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

        
            
          const scrollSpy = new ScrollSpy(document.body, {
            target: '#navbar-example'
          })
        
        
    
        
            
          const scrollSpy = new mdb.ScrollSpy(document.body, {
            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 will be ignored and their corresponding nav items will never be highlighted.

Via jQuery

Note: By default, MDB does not include jQuery and you have to add it to the project on your own.

        
            
          $(document).ready(() => {
            $('.example-class').scrollSpy(options);
          });
        
        
    

Options

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

Name Type Default Description
offset number | null null Pixels to offset from top when calculating position of scroll.
rootMargin string '0px 0px -25%' Intersection Observer rootMargin valid units, when calculating scroll position.
smoothScroll boolean false Enables smooth scrolling when a user clicks on a link that refers to ScrollSpy observables.
target string | DOM element null Specifies element to apply Scrollspy plugin.
threshold array [0.1, 0.5, 1] IntersectionObserver threshold valid input, when calculating scroll position.

Methods

Name Description Example
refresh When using scrollspy in conjunction with adding or removing of elements from the DOM, you’ll need to call the refresh method instance.refresh()
dispose Destroys an element’s tab. instance.dispose()
getInstance Static method which allows you to get the scrollspy instance associated to a DOM element. ScrollSpy.getInstance(dataSpyEl)
        
            
          const dataSpyList = document.querySelectorAll('[data-mdb-scrollspy-init]')
          dataSpyList.forEach((dataSpyEl) => {
            ScrollSpy.getInstance(dataSpyEl).refresh()
          })
        
        
    
        
            
        const dataSpyList = document.querySelectorAll('[data-mdb-scrollspy-init]')
        dataSpyList.forEach((dataSpyEl) => {
          mdb.ScrollSpy.getInstance(dataSpyEl).refresh()
        })
      
        
    

Events

Event type Description
activate.mdb.scrollspy This event fires on the scroll element whenever a new item becomes activated by the scrollspy.
        
            
        const firstScrollSpyEl = document.querySelector('[data-mdb-scrollspy-init]')
        firstScrollSpyEl.addEventListener('activate.mdb.scrollspy', () => {
          // do something...
        })
        
        
    

CSS variables

As part of MDB’s evolving CSS variables approach, scrollspy now use local CSS variables for enhanced real-time customization. Values for the CSS variables are set via Sass, so Sass customization is still supported, too.

Scrollspy CSS variables are in different classes which belong to this component. To make it easier to use them, you can find below all of the used CSS variables.

        
            
        // .nav-pills
        // &.menu-sidebar
        --#{$prefix}scrollspy-menu-sidebar-font-size: #{$scrollspy-menu-sidebar-font-size};
        --#{$prefix}scrollspy-menu-sidebar-color: #{$scrollspy-menu-sidebar-color};
        --#{$prefix}scrollspy-menu-sidebar-line-height: #{$scrollspy-menu-sidebar-line-height};
        --#{$prefix}scrollspy-menu-sidebar-padding-x: #{$scrollspy-menu-sidebar-padding-x};
        --#{$prefix}scrollspy-menu-sidebar-font-weight: #{$scrollspy-menu-sidebar-font-weight};
        --#{$prefix}scrollspy-menu-sidebar-transition: #{$scrollspy-menu-sidebar-transition};
        --#{$prefix}scrollspy-menu-sidebar-margin-y: #{$scrollspy-menu-sidebar-margin-y};
  
        // .nav-link.active,
        // .show > .nav-link
        --#{$prefix}scrollspy-menu-sidebar-active-color: #{$scrollspy-menu-sidebar-active-color};
        --#{$prefix}scrollspy-menu-sidebar-active-font-weight: #{$scrollspy-menu-sidebar-active-font-weight};
        --#{$prefix}scrollspy-menu-sidebar-active-border-width: #{$scrollspy-menu-sidebar-active-border-width};
        --#{$prefix}scrollspy-menu-sidebar-active-border-color: #{$scrollspy-menu-sidebar-active-border-color};
  
        // .collapsible-scrollspy ~ .nav
        --#{$prefix}scrollspy-collapsible-nav-transition-time: #{$scrollspy-collapsible-nav-transition-time};
        
        
    

SCSS variables

        
            
        $scrollspy-menu-sidebar-font-size: 0.8rem;
        $scrollspy-menu-sidebar-color: var(--#{$prefix}body-color);
        $scrollspy-menu-sidebar-line-height: 1.1rem;
        $scrollspy-menu-sidebar-padding-x: 5px;
        $scrollspy-menu-sidebar-font-weight: 400;
        $scrollspy-menu-sidebar-transition: all 0.2s ease-in-out;
        $scrollspy-menu-sidebar-margin-y: 3px;

        $scrollspy-menu-sidebar-active-color: $primary;
        $scrollspy-menu-sidebar-active-font-weight: 600;
        $scrollspy-menu-sidebar-active-border-width: 0.125rem;
        $scrollspy-menu-sidebar-active-border-color: $primary;

        $scrollspy-collapsible-nav-transition-time: 0.5s;