Making smooth anchor tag scrolling compatible with scroll snapping

Viewed 2602

I am using:

html {
    scroll-behavior: smooth;
}

to enable smooth scrolling to html anchor tags. I am also enabling vertical scroll snapping using scroll-snap-type and scroll-snap-align in the css as in the code below. The issue is that I can't get both behaviors to work. To enable scroll snapping I need to set a height on the containing div. This seems to disable the smooth scrolling to html anchor tags. You can experiment with this in the snippet below at full screen. If you delete height: 100vh; in the snippet below, the page will scroll smoothly to the anchors but it will not scroll snap. If you include it, the page will scroll snap but will jump to the anchors instead of smoothly scrolling.

    html {
        scroll-behavior: smooth;
    }

    main {
        height: 100vh;
        overflow: scroll;
        scroll-snap-type: y mandatory;
    }

    section {
        height: 400px;
        scroll-snap-align: start;
    }

    nav {
        position: fixed;
        top: 0;
        color: white;
        width: 100%;
    }

    li {
        display: inline-block;
        list-style-type: none;
    }

    a:visited {
        color: white;
    }

    .one {
        background-color: red;
    }

    .two {
        background-color: blue;
    }

    .three {
        background-color: grey;
    }

    .four {
        background-color: green;
    }
    <nav>
        <ul>
            <li><a href="#section-2">section 2</a></li>
            <li><a href="#section-3">section 3</a></li>
            <li><a href="#section-4">section 4</a></li>
        </ul>
    </nav>

    <main>
        <section id="section-1" class="one">
        </section>
        <section id="section-2" class="two">
        </section>
        <section id="section-3" class="three">
        </section>
        <section id="section-4" class="four">
        </section>
    </main>

2 Answers

Can you please check the below code? Hope it will work for you. If you want smooth scrolling to HTML anchor tags without using JS then you can achive this by using scroll-snap-type,scroll behavior, and scroll-snap-align CSS propeties.

Please refer to this link: https://jsfiddle.net/yudizsolutions/seogca34/1/

main {
  height: 100vh;
  overflow: scroll;
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
}

section {
  height: 100vh;
  scroll-snap-align: start;
}

nav {
  position: fixed;
  top: 0;
  color: white;
  width: 100%;
}

li {
  display: inline-block;
  list-style-type: none;
}

a:visited {
  color: white;
}

.one {
  background-color: red;
}

.two {
  background-color: blue;
}

.three {
  background-color: grey;
}

.four {
  background-color: green;
}
<nav>
  <ul>
    <li><a href="#section-2">section 2</a></li>
    <li><a href="#section-3">section 3</a></li>
    <li><a href="#section-4">section 4</a></li>
  </ul>
</nav>

<main>
  <section id="section-1" class="one">
  </section>
  <section id="section-2" class="two">
  </section>
  <section id="section-3" class="three">
  </section>
  <section id="section-4" class="four">
  </section>
</main>

i use jquery for smooth scroll when click on a tag.& remove some css from your code. maybe this can help

$('nav ul li  a[href^="#"]').on('click', function(event) {
        
      var target = $(this.getAttribute('href'));
      if( target.length ) {
      event.preventDefault();
      $('html, body').stop().animate({
      scrollTop: target.offset().top-80
      }, 1500);
      }
  });
  
  
    main {
        height: 100vh;
    }

    section {
        height: 400px;
    }

    nav {
        position: fixed;
        top: 0;
        color: white;
        width: 100%;
    }

    li {
        display: inline-block;
        list-style-type: none;
    }

    a:visited {
        color: white;
    }

    .one {
        background-color: red;
    }

    .two {
        background-color: blue;
    }

    .three {
        background-color: grey;
    }

    .four {
        background-color: green;
    } 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
        <ul>
            <li><a href="#section-2">section 2</a></li>
            <li><a href="#section-3">section 3</a></li>
            <li><a href="#section-4">section 4</a></li>
        </ul>
    </nav>

    <main>
        <section id="section-1" class="one">
        </section>
        <section id="section-2" class="two">
        </section>
        <section id="section-3" class="three">
        </section>
        <section id="section-4" class="four">
        </section>
    </main>

Related