<nav class="nav">
  <ul class="menu">
    <li><a href="#a">A</a></li>
    <li><a href="#b">B</a></li>
    <li><a href="#c">C</a></li>
    <li><a href="#d">D</a></li>
  </ul>
</nav>
<main class="main">
  <section id="a" class="section">
    <h2>Section A</h2>
  </section>
  <section id="b" class="section">
    <h2>Section B</h2>
  </section>
  <section id="c" class="section">
    <h2>Section C</h2>
  </section>
  <section id="d" class="section">
    <h2>Section D</h2>
  </section>
</main>
body {
  background-color: #333;
  color: #fff;
  font-family: "Teko", sans-serif;
}
.nav {
  background-color: #000;
  border-radius: 10px;
  position: fixed;
  left: 25px;
  top: 25px;
  padding: 0 20px;
}
.menu {
  padding: 0;
  margin: 0;
  display: flex;
  li {
    list-style: none;
    &:not(:first-of-type) {
      margin-left: 10px;
    }
    a {
      text-decoration: none;
      display: block;
      color: #fff;
      font-size: 1.625rem;
      padding: 10px;
    }
  }
}
.main {
}
.section {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 75vh;
  &:nth-child(odd) {
    background-color: #333;
  }
  &:nth-child(even) {
    background-color: #666;
  }
  h2 {
    margin: 0;
    font-weight: bold;
    font-size: 2.5rem;
  }
}
View Compiled
  const easing = t => t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
  const duration = 600;
  const headerHeight = 0;
  const triggers = document.querySelectorAll('a[href^="#"]');

  triggers.forEach( item => {
    item.addEventListener('click', e => {
      e.preventDefault();
      e.stopPropagation();

      const href = item.getAttribute('href');
      const currentPosition = document.documentElement.scrollTop || document.body.scrollTop;
      const targetElement = document.getElementById(href.replace('#', ''));

      if (targetElement) {
        const targetPosition = window.pageYOffset + targetElement.getBoundingClientRect().top - headerHeight;
        const startTime = window.performance.now();

        const loop = nowTime => {
          const time = nowTime - startTime;
          const normalizedTime = time / duration;
          if (normalizedTime < 1) {
            window.scrollTo(0, currentPosition + ((targetPosition - currentPosition) * easing(normalizedTime)));
            window.requestAnimationFrame(loop);
          } else {
            window.scrollTo(0, targetPosition);
          }
        };

        window.requestAnimationFrame(loop);
      }
    });
  });
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.