# ScrollSpy > Automatically update Bootstrap navigation or list group components based on scroll position to > indicate which link is currently active in the viewport. ## How it works The `v-b-scrollspy` directive has a few requirements to function properly: - It must be applied on the element/component containing the `` or `` component(s) where you want to indicate which link is currently active. - Scrollspy requires `position: relative;` on the element you're spying on, usually the ``. - When spying on elements other than the ``, be sure to have a `height` set and `overflow-y: scroll;` applied. - Anchors (``, ``, ``, ``) are required and must have an `href` (either via the `href` or `to` props) that points to an element with that `id` in the container you are spying on. When using the `to` prop, either set the `path` ending with `#id-of-element`, or set the location property `hash` to `#id-of-element`. When successfully implemented, your nav or list group will update accordingly, moving the `active` state from one item to the next based on their associated targets. ### Example using navs Using `v-b-scrollspy` on a `` component to monitor the scrolling on ``. Scroll the area below the navbar and watch the active class change. The dropdown items will be highlighted as well. ```html ``` ### Example using nested navs Scrollspy also works with nested ``. If a nested `` is active, its parent()s will also be active. Scroll the area next to the navbar and watch the active class change. ```html ``` ### Example using list group Scrollspy also works with `` when it contains ``s that have a _local_ `href` or `to`. Scroll the area next to the list group and watch the active state change. ```html ``` ## Using scrollspy on components with the `to` prop When Vue Router (or Nuxt.js) is used, and you are generating your links with the `to` prop, use one of the following methods to generate the appropriate `href` on the rendered link: ```html link text link text ``` Scrollspy works with both `history` and `hash` routing modes, as long as the generated URL ends with `#id-of-element`. ## Directive syntax and usage ``` v-b-scrollspy:arg.mod1.mod2="option" ``` Where: - `arg` is the ID (minus the `#`) of the element to monitor scrolling on. Optional (defaults to `body`. Can be overridden by `option`) - `mod1` & `mod2` can be an `offset` number or string `method` (see config object below). Order of the modifiers is not important. Both are optional - `option` can be a string identifying the `element` to monitor scrolling on, a numeric `offset`, or a configuration object (see below). Optional **Note:** The directive is applied backwards compared to native Bootstrap v4. In **BootstrapVue** the `v-b-scrollspy` directive is applied to the target element that has the links to be activated, and the arg or option specifies which element to monitor (spy) scrolling on. The directive an be applied to any containing element or component that has ``, ``, `` (or `` tags with the appropriate classes), a long as they have rendered `href` attributes that point to elements with the respective `id`s in the scrolling element. ### Config object properties ```js const config = { element: 'body', offset: 10, method: 'auto', throttle: 100 } ``` | Property | Type | Default | Description | | ---------- | ------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `element` | String or Reference | `'body'` | Element to be monitored for scrolling. Can be an ID (`#foo`), a css Selector (`#foo div`), or a reference to an element/component node. If a CSS string, then the first matching element is used. If an ID is used it must start with `#`. | | `offset` | Number | `10` | offset (in pixels) from top of scrolling viewport before triggering active state. | | `method` | String | `'auto'` | `position` will calculate target offsets relative to the scroll container. `offset` will calculate the target offsets relative to the top of the window/viewport. `auto` will choose `offset` if scroll element is `body`, else the method is `position`. | | `throttle` | Number | `100` | Timeout in `ms` for resize events to stop firing before recalculating offsets. | If args/modifiers and a value (object or number) is passed, the value takes precedence over the arg and modifiers. If any of the options are invalid types, then an error is written to the console. ### Config notes - If scroll element is not present, then we assume scrolling on `` - If scroll element is a CSS selector, the first found element is chosen - If scroll element is not found, then ScrollSpy silently does nothing **Important! Requires relative positioning** No matter the implementation method, scrollspy requires the use of `position: relative;` on the element you're scrolling on. In most cases this is the ``. When scrollspying on elements other than the ``, be sure to have a CSS `height` set and `overflow-y: scroll;` applied. ### Directive use examples Assume `` is the scroll element, and use default offset of 10 pixels ```html
Foo Bar
``` Assume `` is the scroll element, and use offset of 20 pixels ```html
Foo Bar
``` Element with ID `#foo` is the scroll element, and use default offset of 10 pixels ```html
Foo Bar
``` Element `#foo` is the scroll element, and use offset of 20 pixels ```html
Foo Bar
``` Element `#foo` is the scroll element, and use offset of 25 pixels ```html
Foo Bar
``` Element `#foo` is the scroll element, and use default offset of 10 pixels (note single quotes around value) ```html
Foo Bar
``` Pass object as config. `element` can be a CSS ID (i.e `#foo`), a CSS selector (i.e. `body`), or a node reference ```html
Foo Bar
``` ## Events Whenever a target is activated, the event `bv:scrollspy::activate` is emitted on `$root` with the target's ID as the argument (i.e. `#bar`) ```js const app = new Vue({ el: '#app', created() { this.$root.$on('bv::scrollspy::activate', this.onActivate) }, methods: { onActivate(target) { console.log('Received event: "bv::scrollspy::activate" for target ', target) } } }) ```