Vanilla Javascript Smooth Scroll Tutorial

Check out my courses and become more creative!

Here is a quick tutorial on how to do the smooth scroll effect in vanilla javascript. Browser support is really good for the request animation animation so I wouldn’t worry about it too much. Hope you guys enjoy this Javascript tutorial.
Ease functions :
Request time frame :

Follow my Twitter:

Please watch: “Should You Become A Software Engineer?”


Original source

26 thoughts on “Vanilla Javascript Smooth Scroll Tutorial

  • April 18, 2020 at 19:48

    Really nice tutorial, but I faced the following error: when I used the code with a navbar which contained the links as nav-items. the function wouldn't scroll properly.
    The error occured, because the .getBoundingClientRect().top function already returns the distance to the selector based on the window.y position.
    So when you click a nav-link twice the second time your targetPosition is equal 0 while your startPosition stays the same e.g 1200
    => distance = targetPosition(0) – startPosition(1200) = -1200 which scrolls back your window to the very top which is of course not right.
    Basically we don't need the distance variable instead we should change the ease parameter distance to targetPosition
    => var run = ease(timeElapsed, startPosition, targetPosition, duration);

    If you want to use the code with a navbar I would also recommend to subtract your navbar-height from the targetPosition variable.

  • April 18, 2020 at 19:48

    Hello Dev, I've really enjoyed your tutorial. I'm a beginner in javascript. I followed your code but lost it at the end. I've coded exactly as you did. But upon clicking smooth scroll isn't working but without click event, it works fine when reloading the website every time. Here is my code (part I think is wrong). Your help will be much appreciated.

    var section1= document.querySelector('.first');

    var section2= document.querySelector('.second');







  • April 18, 2020 at 19:48

    Great video. There is an issue with this function though as Brian Cook has point out below.
    Please change the targetPosition variable to this:

    var targetPosition = target.getBoundingClientRect().top + window.pageYOffset;
    The problem is that the function doesn't take into account when you have already scrolled down the page. It calculates the scroll distance as if it were at pageYOffset = 0 every time.
    But this is still a great video and was super helpful! thank you for all your hard work Dev Ed.

  • April 18, 2020 at 19:48

    One small addition to the code 🙂
    Beside what Michal Wagner said (I was also struggling and figured that I need to change distance to targetPosition), I wrote this to make all links with # in the href scroll to the desired target (with the same id as the href value) without the need to call the function for each individual element.
    So, after your code, write:

    //get all the links on the page containing # in the href (^= means starting with)
    const anchorLinks = document.querySelectorAll('a[href^="#"]');

    anchorLinks.forEach((link) => {
    // get the target element by getting the href value from each link
    let scrollTarget = link.getAttribute('href');
    // for clicking on any of the links
    link.addEventListener('click', (e) => {
    // we need to prevent default behaviour which would be just jumping to the element without scrolling
    // call your fancy animated scroll function

    Thanks for the video!

  • April 18, 2020 at 19:48

    I found easier way to make your website responding in the same way

    html {
    scroll-behavior: smooth;

    Does it have any relation in what've done?

    Btw, well done.

  • April 18, 2020 at 19:48

    It's great but you can do the same effect without javascript.
    <a href="#content">Click to scroll</a>
    <section id="home">
    // put content here
    <section id="content">
    // put another content here

    html {scroll-behaivor:smooth;}

    And thats all

  • April 18, 2020 at 19:48

    Thank you you tutorial is really helpful, but you don't need to calculate the distance with a substraction because target.getBoundingClientRect().top; is the distance from above the window (relative to the current scroll) to the Y coordinate of the target in the window

  • April 18, 2020 at 19:48

    hi, how can i use one header for all my html pages? something in html( or css, js) equivalent of include in php? so i don't need to copy and paste in each page and when have some changes to do i just change one file?
    thanks for your tutorial

Leave a Reply