Search code examples
javascripthtmlcssanchor-scroll

How to add smooth Scrolling to single anchor instead of whole page


I have created 2 anchors within my page As of default , whenever one clicks on anchor link ,it directly jumps to the requested section

One easy way of enabling smooth Scrolling is adding this in CSS file but it affects the whole html page , I don't want that

i want this smooth Scrolling property to only apply to a single anchor within my page ( lets say the section 1 anchor for this example ) and not every anchors universally

Html Codes are included below in snippets

html {
  scroll-behavior: smooth;
}
<a href="#Section1">Section 1</a><br>
<a href="#Section2">Section 2</a>

<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>

<a class="anchor" id="Section1">&nbsp;</a>

<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>
<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>1<br>

<a class="anchor2" id="Section2">&nbsp;</a>


Solution

  • Here is my solution using (Vanilla) JavaScript.

    I just toggles the className of the <html> element dependent on the data-smooth-scroll attribute being set on the link.

    "use strict";
    
    document.addEventListener('click', function(e) {
      var className = 'smooth';
      var classList = document.documentElement.classList;
      if (e.target.dataset.smoothScroll) {
        classList.add(className)
      } else {
        classList.remove(className)
      }
    })
    html.smooth {
      scroll-behavior: smooth;
    }
    
    section {
      width: 80%;
      border: 1px solid gold;
      margin: 50px auto;
      height: 100vh;
    }
    <a href="#Section1">Section 1</a><br>
    <a href="#Section2">Section 2</a>
    <a href="#Section3" data-smooth-scroll="1">Section 3</a>
    
    <a class="anchor" id="Section1">&nbsp;</a>
    <section>
      <h2>Section 2</h2>
    </section>
    
    <a class="anchor" id="Section2">&nbsp;</a>
    <section>
      <h2>Section 2</h2>
    </section>
    
    <a class="anchor" id="Section3">&nbsp;</a>
    <section>
      <h2>Section 3</h2>
    </section>

    If you don't want the link to decide whether to smooth-scroll or not but the target anchor instead, this should work

    "use strict";
    
    document.addEventListener('click', function(e) {
      var className = 'smooth';
      var classList = document.documentElement.classList;
      classList.remove(className)
      if (e.target.tagName.toLowerCase() === 'a') {
        var id = e.target.hash.replace(/^#/, '')
        var anchor = document.getElementById(id);
        
        if (anchor && anchor.dataset.smoothScroll) {
          classList.add(className)
        }
      }
    })
    html.smooth {
      scroll-behavior: smooth;
    }
    
    section {
      width: 80%;
      border: 1px solid gold;
      margin: 50px auto;
      height: 100vh;
    }
    <a href="#Section1">Section 1</a><br>
    <a href="#Section2">Section 2</a>
    <a href="#Section3">Section 3</a>
    
    <a class="anchor" id="Section1">&nbsp;</a>
    <section>
      <h2>Section 2</h2>
    </section>
    
    <a class="anchor" id="Section2" data-smooth-scroll="1">&nbsp;</a>
    <section>
      <h2>Section 2</h2>
    </section>
    
    <a class="anchor" id="Section3">&nbsp;</a>
    <section>
      <h2>Section 3</h2>
    </section>