The smooth scrolling feature fails to function properly in Lenis when clicking on links with specified IDs

Is there a reason why the scroll-behavior: smooth property doesn't function properly when Lenis library for smooth scrolling is included? It seems to work fine when the Lenis code is commented out, but once it's added back in, the scrolling isn't as smooth when clicking on the tag with the specified ID.

const lenis = new Lenis({
  duration: 2.5
})

function raf(time) {
  lenis.raf(time)
  requestAnimationFrame(raf)
}
requestAnimationFrame(raf)

lenis.on('scroll', ScrollTrigger.update)

gsap.ticker.add((time) => {
  lenis.raf(time * 1000)
})
html {
  scroll-behavior: smooth;
}
 <h2><a class="c-btn" href="#pages-main">scroll down</a></h2>
 
  <section id="pages-main"></section>

Is there a reason why the scroll-behavior: smooth property doesn't function properly when Lenis library for smooth scrolling is included? It seems to work fine when the Lenis code is commented out, but once it's added back in, the scrolling isn't as smooth when clicking on the tag with the specified ID.

const lenis = new Lenis({
  duration: 2.5
})

function raf(time) {
  lenis.raf(time)
  requestAnimationFrame(raf)
}
requestAnimationFrame(raf)

lenis.on('scroll', ScrollTrigger.update)

gsap.ticker.add((time) => {
  lenis.raf(time * 1000)
})
html {
  scroll-behavior: smooth;
}
 <h2><a class="c-btn" href="#pages-main">scroll down</a></h2>
 
  <section id="pages-main"></section>

Answer №1

By implementing the CSS property scroll-behavior: smooth on the html element, scrolling behavior for links with hash tags (#) can be improved. However, this may cause issues with normal scrolling functionality as it seems that lenis scroll controls the scroll behavior on the html element and does not maintain smooth scrolling for other scenarios.

To address this issue, a solution was devised by incorporating the following fix alongside the initialization code for lenis -

// Fix for internal id links
document.querySelectorAll('a[href^="#"]').forEach((el) => {
  el.addEventListener('click', (e) => {
    e.preventDefault()
    const id = el.getAttribute('href')?.slice(1)
    if (!id) return
    const target = document.getElementById(id)
    if (target) {
      target.scrollIntoView({ behavior: 'smooth' })
    }
  })
})

However, one drawback of this approach is that it does not update the URL with the corresponding #id. Attempts to manually adjust the URL using

document.location.hash = "#id"
will result in reverting back to instant scrolling instead of smooth scrolling.

Answer №2

import { LenisInstance, ScrollToParams, useLenis } from "@studio-freight/react-lenis";

// Utilizing the useLenis hook to retrieve a LenisInstance
  const myLenis: LenisInstance = useLenis();

  // Defining a function for smooth scrolling
    const handleScroll = (targetElem: string | number | HTMLElement)=>{

    if (targetElem) {
      const scrollParams: ScrollToParams = {
        offset: 0,
        lerp: 0.1,
        duration: 1.5,
        easing: (rawVal: number) => rawVal,
        immediate: false,
        lock: false,
        force: false,
      };

      myLenis.scrollTo(targetElem, scrollParams);
    }
  }

This code utilizes react-lenis, but it could also be compatible with the standard lenis package.

Answer №3

If you're looking for a solution, check out the Lenis documentation. You have two options:

<a href="#anchor" onclick="lenis.scrollTo('#anchor')">scroll to anchor</a>

Alternatively, you can use a function called scrollTo(target, options)

target: the destination number: pixels to scroll string: CSS selector or keyword (top, left, start, bottom, right, end) HTMLElement: DOM element

Available options are: offset(number): same as scroll-padding-top lerp(number): animation smoothness duration(number): animation duration (in seconds) easing(function): animation style immediate(boolean): skip animation effects lock(boolean): prevent scrolling until reaching target force(boolean): reach target regardless of status onComplete(function): triggered upon reaching target

Answer №4

After some troubleshooting, I found that the best fix was to disable the lenis-smooth rule in the CSS file.

/* .lenis.lenis-smooth {
    scroll-behavior: auto !important;
  } */

I'm positive this solution will work for you as well!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide to adding a theme switcher feature to your current React website

Currently, I am faced with a challenge involving two theme files, theme.js and theme-dark.js, within the context of a complex React-based website. Despite having already set up the site, I am struggling to find a way to allow users to seamlessly switch bet ...

Resizing a column in the Bootstrap CSS grid causes adjacent columns to move

I am currently working with a bootstrap grid that includes an expand component. The issue I am facing is that when I expand one column, the other columns in the same row also shift. Is there a way to make each column independent of the others? expand co ...

Accessing the react-bootstrap tab using the history feature in React

Currently, I am in the process of developing a multi-form page that includes login, registration, and lost password functionalities displayed using tabs with react-bootstrap. The technologies I am using for this project are react 17.0.2, react-bootstrap 2 ...

What is the reason behind not requiring to invoke the next function in a Sails.js controller method, even when it includes an asynchronous database query?

Sample controller function: fetchArticles: function(req, res) { Articles.find({}).exec(function(err, articles) { res.json(articles) // It appears this part is asynchronous // Is next() required here? }) } In my experience, I typicall ...

Ways to delay the inner function's output?

Need help with making a function return only after its inner function is called. See below for the code snippet - function x() { function y() { // Inner function logic } return result; // This should be returned only after function y is ca ...

Pressing the tab key while using Angular will halt any additional processes from running

I recently integrated a search bar into my Angular application. When I enter text in the input field, a customized dropdown menu appears below it. However, when I press the tab key, I expect the dropdown to close and for the focus to shift to the next inpu ...

Having trouble with the tooltip feature in Bootstrap?

I've searched high and low, including on this site! I've experimented with all sorts of code, but nothing seems to make the tooltips function in BootStrap. It's beginning to really frustrate me!! Does anyone happen to have the working js co ...

Modify the HTML select tag to toggle from a selected checkbox

What should I do when a certain option is checked in the checkbox, and that label needs to be shown in the select tag? https://i.stack.imgur.com/ZxRNF.png Checkbox input <input type="checkbox" class="toggle-product pull-right" @if(!isset($restrictedPr ...

The MUI component with hideBackDrop={true} is preventing me from clicking outside of the Drawer component to close it

I implemented a Drawer component which opens when an icon on the Map is clicked. The drawer menu appears along with a backshadow that drops over the map. Interestingly, clicking on the map while the backshadow is displayed closes the drawer without any i ...

Encountering a "file or directory not found" error during the installation of ply using

I recently stumbled upon an interesting project for testing Rest APIs. I was in the process of installing ply from https://github.com/ply-ct/ply npm install ply-ct --save-dev Encountered this error, wondering if anyone has a solution npm WARN saveError EN ...

Leveraging createMuiTheme to customize default styles for divs, paragraphs, and the body element

Seeking guidance on customizing a Material UI Theme I aim to modify the default styles for elements like <body>. Currently, at the root of my React tree: import theme from './mui-theme' ReactDOM.render( <Router> <ThemePr ...

Unexpected behavior from vuelidate triggered on blur

I have implemented vuelidate for form validation. My goal is to validate user input either when they move to the next input field or click outside of the current one. <div class="form-group col-md-6" :class="{invalid: $v.partner.email.$ ...

Reactively responsive table view

I am new to CSS and recently discovered a responsive table on this website that I would like to incorporate into my application. My challenge is figuring out how to switch the table layout from left to right (headers on the right and values on the left) w ...

Creating a fixed navigation bar that stays at the top of the page when scrolling

I am trying to create a navigation bar similar to the one seen on W3School's website. I would like the navigation bar to overlap the header when scrolling down, and for the header to appear above the nav bar when scrolling back to the top. Despite m ...

Adding CSS properties to an image within the ImageResourceCell of a CellTable

After creating a CellTable with an image column in GWT using ImageResource, I encountered a problem. I needed to change some CSS properties of the image such as size or adding 'cursor="pointer" for a click event, but was unsure how to do so. When insp ...

Styling Javascript Objects

[ [ {"path":"path2","value":"kkk"}, {"path":"path0","value":"uuu"}, {"path":"path1","value":"ppp"} ] ] The result obtained from my manipulation is shown above. However, I require the format to be as depicted below: ["path":"pat ...

jQuery function failing to produce the intended results

I am trying to apply the active class to the last img element using HTML and jQuery Below is my code in HTML and jQuery: function initialSteps() { $(".row").find("column:last").find("img:first").className += " active"; // this does not work either ...

Error received - CORS request denied on Firefox browser (Ubuntu)

I encountered a CORS error (CORS request rejected: https://localhost:3000/users) while attempting to register a new user. This issue arose from content in the book Building APIs with node.js, Chapter 12. I am currently using Firefox on Ubuntu and have tr ...

Adjust the size of both the parent div and child textarea dynamically to ensure they are always equal without setting specific height or width values

To ensure that the height and width of a parent div that contains a child textarea are exactly equal, you can utilize the following CSS code snippet: https://jsfiddle.net/BwVQZ/7/ <div> <textarea></textarea> </div> div{ hei ...

AngularJS is not responding to a 400 bad request

Despite my efforts to find solutions on Google and Stack Overflow for similar or identical issues, as a newcomer, none of them have provided me with any insight on how to resolve the issues in my code. Here is the script I am working with: $http.post(&ap ...