Scrollto is a plugin that manages interaction scroll with hash links or any node.


Import the javascript file with import 'xtendui/src/scrollto'.

Initialize manually within javascript with new Xt.Scrollto(document.querySelector('.my-container'), {/* options */}).


Use Tailwind CSS variants on:, group-on: to assign animations to anchors elements.

You can also scroll to a Node also if not anchored using the event scrollto.trigger.xt.scrollto.

This demo uses scroll sticky see documentation for more info.

Do not assign other components to anchors or the components activations conflict.

Try the demo on a new page to preview location hash changes.

You can also set scroll position without gsap.

It works also inside overlay and it automatically open overlay and all parent components with openauto: true.

Try the demo on a new page to preview location hash changes.

Toggle Integration

You can use the Scrollto component in conjunction with any toggle component (toggle, drop, overlay, slider, tooltip). It also integrates with the toggle hash interaction.

SyntaxDefault / ArgumentsDescription
Optionscrollto:Boolean|Query|StringfalseOn activation trigger scrollto to self.container or to a query or to type can be elements, targets, elementsInner, targetsInner
OptionscrolltoInit:BooleanfalseScrollto also on initialization (data-xt-hash or .on or options.min etc..)

Use a[role="button"] instead of a[href]. Use queue: false for proper browser back button.

Try the demo on a new page to preview location hash changes.


Here are the main javascript options.

SyntaxDefault / ArgumentsDescription
Optiondebug:BooleanfalseDebug on console
Optionanchors:Array[href*="{hash}"]:not([href$="#"])Query for hash links where {hash} is the hash part of the link
Optionscrollers:Query'.xt-overlay:not([data-xt-overlay-disabled])'Query for scroll nodes besides document (ordered parent > child)
Optionclass:String'on'Activation class for anchors
Optionevents:String|false'scroll off.xt.overlay'Events of self.scrollers that triggers activation
OptionscrollActivation:BooleantrueActivate anchors automatically on scroll
OptionscrollDelay:Number200Delay on scroll checks
Optionhash:BooleanfalseUpdate url with hash on anchors, if false you can use [data-xt-scrollto-hash="true"] or [data-xt-scrollto-hash="false"] on each link
Optionposition({ self }):Function<Function>Positioning function that sets self.position, return Number
Optionspace({ self }):Function<Function>Positioning space window top that sets, return Number
Optionduration({ self }):Function<Function>Scroll duration depending on self.scroll.scrollTop and self.position that sets self.duration, return Number

Default functions as follow.

position: ({ self }) => {
  const rect =
  let position = + self.scroller.scrollTop
  if (self.scroller !== document.scrollingElement) {
    const rectScrollElement = self.scroller.getBoundingClientRect()
    position = position -
  return position
space: () => {
  return window.innerHeight / 6
duration: () => {
  const overlay ='.xt-overlay')
  // instant scroll on initial or hashchange or inside overlay and not already activated
  if (self.initial || self.hashchange || (overlay && !overlay.classList.contains('in'))) return 0
  return 1

Match Media

You can add additional options that gets added on match media query. You can use different queries with different and nested options.

SyntaxDefault / ArgumentsDescription
Optionmatches:ObjectfalseAdd additional options on match media query


You can get self object from DOM node on Xtend UI components with Xt.get.

let self = Xt.get({ name: 'xt-scrollto', el: document.querySelector('.my-container') })

You can set default options for all components of the same type, with Xt.options.

Xt.options['xt-scrollto'] = {
  debug: true,


Listen to events, for listeners use this guideline.

SyntaxDOM ElementDescription
Eventscrollto.xt.scrolltocontainerScrollto event
Eventinit.xt.scrolltocontainerInit or reinit event
Eventstatus.xt.scrolltocontainerStatus event (enabled or disabled)
Eventdestroy.xt.scrolltocontainerDestroy event


Trigger events on DOM node.

SyntaxDOM ElementDescription
Eventscrollto.trigger.xt.scrollto<any DOM node>Scroll to a Node also if not anchored


Access properties by getting self object.

let self = Xt.get({ name: 'xt-scrollto', el: document.querySelector('.my-container') })
const container = self.container

If you want to force the self.hashchange value manually for instant duration set Xt.scrolltoHashforce to true or false just before triggering scrollto.trigger.xt.scrollto or changing location.hash.

PropertycomponentName:StringComponent name (used in Xt.get)
Propertyoptions:ObjectFinal options
Propertyinitial:BooleanIf initial or reset activation
Propertydisabled:BooleanIf component disabled
Propertycontainer:NodeContainer node
Propertyhashchange:BooleanIf browser hash change activation
Propertytarget:NodeCurrent scroll target
Propertyscrollers:NodeAll scrolling element
Propertyscroller:NodeCurrent scrolling element
Propertyposition:NumberCurrent scroll position
Propertyspace:NumberCurrent scroll space
Propertyduration:NumberCurrent scroll duration


Call methods by getting self object.

let self = Xt.get({ name: 'xt-scrollto', el: document.querySelector('.my-container') })
self = null
Methodself.reinit()Reinit component
Methodself.disable()Disable component
Methodself.enable()Enable component
Methodself.destroy()Destroy component