Search code examples
javascriptcsssmooth-scrolling

Javascript smooth scroll with scroll-margin-top creates a jump at the end


I'm implementing smooth scrolling on my website using JavaScript, and I've encountered an issue with CSS scroll-margin-top causing a jump at the end. I'm using the following CSS for scroll margins:

class or div {
  scroll-margin-top: 6rem;/*any size*/
}

I have a smooth scroll JavaScript function as well. The problem is that when scrolling to these sections, there's a noticeable jump when reaching the end of the scroll.

Here is the JavaScript code:

    var ssSmoothScroll = function () {
      $('a[href^="#"], area[href^="#"]').on('click', function (e) {
        var target = $($(this).attr('href'));
        if (target.length) {
          e.preventDefault();
          $('html, body').stop().animate({
            scrollTop: target.offset().top
          }, cfg.scrollDuration, 'swing', function () {
            window.location.hash = target.attr('id');
          });
        }
      });
    };  

How can I resolve this issue and maintain smooth scrolling without the jump at the end?

The JsFiddle demo


Solution

  • the scroll-margin-top value for the target element and subtracts it from the scrolling destination.

    $(document).ready(function () {
      $('a[href^="#"], area[href^="#"]').on('click', function (e) {
        var target = $($(this).attr('href'));
        if (target.length) {
          e.preventDefault();
          var scrollMargin = target.css('scroll-margin-top'); // Get scroll-margin-top value
          var offset = scrollMargin ? parseInt(scrollMargin) : 0; // Parse the value
          $('html, body').stop().animate({
            scrollTop: target.offset().top - offset // Consider scroll-margin-top
          }, 1000, 'swing', function () {
            window.location.hash = target.attr('id');
          });
        }
      });
    });
     body {
          margin: 0;
          padding: 0;
        }
        
        #first,
        #second,
        #third,
        #fourth,
        #fifth {
          scroll-margin-top: 6rem;
        }
    
        /* Additional styles for demonstration purposes */
        section {
          height: 100vh;
          display: flex;
          justify-content: center;
          align-items: center;
          font-size: 2rem;
        }
    <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
     <nav>
        <ul>
          <li><a href="#first">first</a></li>
          <li><a href="#second">second</a></li>
          <li><a href="#third">third</a></li>
          <li><a href="#fourth">fourth</a></li>
          <li><a href="#fifth">fifth</a></li>
        </ul>
      </nav>
    
      <section id="first">first</section>
      <section id="second">second</section>
      <section id="third">third</section>
      <section id="fourth">fourth</section>
      <section id="fifth">fifth</section>