Tips for gently scrolling instead of quickly scrolling all at once

As a novice in HTML, I have a question about navigation to an ID targeted by an anchor tag. For example:

When I execute this code, it quickly jumps to the specified ID but I would like to incorporate animations. Is there a way to achieve this?

Answer №1

To achieve a smooth page scroll to an anchor on the same page, you can utilize jQuery.

Check out this code snippet that includes logic to differentiate jump links from other links:

// Identifying all links with hashes
$('a[href*="#"]')
  // Removing links that do not lead anywhere
  .not('[href="#"]')
  .not('[href="#0"]')
  .click(function(event) {
    // Links within the same page
    if (
      location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') 
      && 
      location.hostname == this.hostname
    ) {
      // Determining the element to scroll to
      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
      
      // Checking if a scroll target exists
      if (target.length) {
        // Preventing default only if there will be an animation
        event.preventDefault();
        
        $('html, body').animate({
          scrollTop: target.offset().top
        }, 1000, function() {
          // Callback after animation
          // Changing focus is necessary!
          var $target = $(target);
          $target.focus();
          
          // Verifying if the target was focused
          if ($target.is(":focus")) { 
            return false;
          } else {
            $target.attr('tabindex','-1'); // Adding tabindex for non-focusable elements
            $target.focus(); // Setting focus again
          };
        });
      }
    }
  });

Answer №2

Your HTML code might look something like this:

<a href = "#start-heading">Jump to start of content</a>
<div id = "table-of-contents">...</div>
<h1 id = "start-heading">Chapter 1</h1>

Implement the following JavaScript for smooth scrolling when clicking on the start heading:

document.querySelector("#start-heading").onclick = e=>{
  this.scrollIntoView({ 
    behavior: 'smooth' 
  });
  e.preventDefault();
  return false;
};

document.querySelector("#start-heading").onclick = e=>{
  document.querySelector(this.href).scrollIntoView({ 
    behavior: 'smooth' 
  });
  e.preventDefault();
  return false;
};
<a href = "#start-heading">Jump to start of content</a>
<div id = "table-of-contents">
  <!-- Content of the table of contents here -->
</div>
<h1 id = "start-heading">Chapter 1</h1>
<!-- More content related to Chapter 1 -->
<p>
<!-- Bacon ipsum and other placeholder text here -->
</p>

<script>
// Smooth scroll polyfill script
// Author: Dustan Kasten, Jeremias Menichelli
// Source: https://iamdustan.github.io/smoothscroll

(function(w, d, undefined) {
  'use strict';

  /* Rest of the script goes here */

})(window, document);</script>

Answer №3

For a detailed array of techniques for achieving smooth scrolling effects, please refer to my response here.


You have the option to configure the CSS property scroll-behavior with a value of smooth. This setting enables a smooth scrolling experience when clicking on anchor tags that target specific elements.

html, body{
  scroll-behavior: smooth;
}
a, a:visited{
  color: initial;
}
<a href="#elem">Scroll To Element</a>
<div id="elem" style="margin: 500px 0px;">Div</div>

To achieve precise scrolling positions within a defined time frame, window.requestAnimationFrame can be utilized by calculating the correct positioning continuously. In cases where requestAnimationFrame is not supported, setTimeout serves as an alternative method.

/*
   @param pos: the y-position to scroll to (in pixels)
   @param time: the exact amount of time the scrolling will take (in milliseconds)
*/
function scrollToSmoothly(pos, time) {
    var currentPos = window.pageYOffset;
    var start = null;
    if(time == null) time = 500;
    pos = +pos, time = +time;
    window.requestAnimationFrame(function step(currentTime) {
        start = !start ? currentTime : start;
        var progress = currentTime - start;
        if (currentPos < pos) {
            window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos);
        } else {
            window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time));
        }
        if (progress < time) {
            window.requestAnimationFrame(step);
        } else {
            window.scrollTo(0, pos);
        }
    });
}

/*
   @param time: the exact amount of time the scrolling will take (in milliseconds)
   @param pos: the y-position to scroll to (in pixels)
*/
function scrollToSmoothly(pos, time) {
    var currentPos = window.pageYOffset;
    var start = null;
    if(time == null) time = 500;
    pos = +pos, time = +time;
    window.requestAnimationFrame(function step(currentTime) {
        start = !start ? currentTime : start;
        var progress = currentTime - start;
        if (currentPos < pos) {
            window.scrollTo(0, ((pos - currentPos) * progress / time) + currentPos);
        } else {
            window.scrollTo(0, currentPos - ((currentPos - pos) * progress / time));
        }
        if (progress < time) {
            window.requestAnimationFrame(step);
        } else {
            window.scrollTo(0, pos);
        }
    });
}
<button onClick="scrollToSmoothly(document.querySelector('div').offsetTop, 300)">
Scroll To Div (300ms)
</button>
<button onClick="scrollToSmoothly(document.querySelector('div').offsetTop, 200)">
Scroll To Div (200ms)
</button>
<button onClick="scrollToSmoothly(document.querySelector('div').offsetTop, 100)">
Scroll To Div (100ms)
</button>
<button onClick="scrollToSmoothly(document.querySelector('div').offsetTop, 50)">
Scroll To Div (50ms)
</button>
<button onClick="scrollToSmoothly(document.querySelector('div').offsetTop, 1000)">
Scroll To Div (1000ms)
</button>
<div style="margin: 500px 0px;">
DIV<p/>
<button onClick="scrollToSmoothly(0, 500)">
Back To Top
</button>
<button onClick="scrollToSmoothly(document.body.scrollHeight)">
Scroll To Bottom
</button>
</div>
<div style="margin: 500px 0px;">
</div>
<button style="margin-top: 100px;" onClick="scrollToSmoothly(500, 3000)">
Scroll To y-position 500px (3000ms)
</button>

For intricate scenarios, consider utilizing the SmoothScroll.js library, which supports smooth scrolling in both vertical and horizontal directions, operation within various container elements, diverse easing behaviors, relative scrolling adjustments, and more.

var easings = document.getElementById("easings");
for(var key in smoothScroll.easing){
    if(smoothScroll.easing.hasOwnProperty(key)){
        var option = document.createElement('option');
        option.text = option.value = key;
        easings.add(option);
    }
}
document.getElementById('to-bottom').addEventListener('click', function(e){
    smoothScroll({yPos: 'end', easing: easings.value, duration: 2000});
});
document.getElementById('to-top').addEventListener('click', function(e){
    smoothScroll({yPos: 'start', easing: easings.value, duration: 2000});
});
<script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="95c6f8fafae1fdc6f6e7faf9f9d5a4bba7bba5">[email protected]</a>/src/smoothscroll.min.js" integrity="sha384-UdJHYJK9eDBy7vML0TvJGlCpvrJhCuOPGTc7tHbA+jHEgCgjWpPbmMvmd/2bzdXU" crossorigin="anonymous"></script>
<!-- Extracted from one of the library examples -->
Easing: <select id="easings"></select>
<button id="to-bottom">Scroll To Bottom</button>
<br>
<button id="to-top" style="margin-top: 5000px;">Scroll To Top</button>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Struggling to Make Text Overlay Transparent and Slide Only to the Right

Can someone help me make my image have an opaque overlay with text that slides only right when hovered over? Currently, it's sliding both right and up. Any suggestions on how to fix this issue would be greatly appreciated. Thank you. html, body{ ...

Troubleshooting issue: Bootstrap not loading with custom CSS on Flask platform

Recently, I started learning Flask and created a basic web application. Utilizing Bootstrap 5 for my project, I encountered an issue where my custom CSS fails to work when the Bootstrap stylesheet is loaded (removing it resolves the problem). My folder st ...

Issue with Vue's v-autocomplete component not clearing the user's typed text when an item is selected from

I have implemented a vue v-autocomplete component on my page. I am unsure if the current behavior is as expected, as I cannot find similar examples demonstrating this functionality. The issue arises when a user begins typing in text and the autocomplete ...

Send PS3 through user agent for redirection

If a user is accessing the site using a PS3, I want them to be redirected to a different webpage Below is the code snippet I have been attempting to use: <script language=javascript> <!-- if ((navigator.userAgent.match(/iMozilla/i)) || (navigato ...

Conceal location labels in maps provided by tilehosting.com

I am currently in the initial stages of developing a maps web application and I want to incorporate maps from tilehosting.com along with the leaflet library (leafletjs.com). Overall, it seems to be working fine, but I'm struggling with hiding the def ...

A simple guide to viewing a sequential list of loaded stylesheets in Google Chrome

I've been trying to figure out the loading order of CSS stylesheets in Google Chrome, but I'm finding it a bit confusing. Despite my attempts to use Dev Tools -> Network tab -> filter for Stylesheets, I keep getting different results each t ...

Encountering silence: React JS fetch call left unanswered by Sinatra server

Exploring the realms of Sinatra and React JS, I am venturing into making a GET call from my React website to a Sinatra server in order to display plain text. The Sinatra Server script: require 'sinatra' set :root, 'lib/app' before d ...

Activating the spinning wheel page-loading indicator in the browser through Socket.IO

Currently, I am constructing a web application using Node.js along with Socket.IO for managing data transfer between the client and server components. The central component of my web app is a content feed. To fetch the contents of the newsfeed, my client- ...

Transformation of Array of Objects to Array of Values using Node.js

I am looking to transform the following: [{ prop1: '100', prop2: false, prop3: null, prop4: 'abc' }, { prop1: '102', prop2: false, prop3: null, prop4: 'def' } ] into this format: [[100,false,null,'abc&ap ...

"Here's how you can mark an option as selected in Angular, either from the component or the HTML file

When it comes to my form, I have a select menu that sends data to an SQL database and then fetches it back when it is called for editing. The value being edited should be displayed in the select menu option as selected. Here's a peek at my code: < ...

Use ng-repeat to dynamically calculate the sum of values in a textbox in AngularJS

Greetings everyone! I am currently utilizing AngularJS and I am attempting to sum the values that are entered in an ng-repeat text box, row by row. However, my current solution sums up all the data instead of doing it row by row. Can anyone offer guidance ...

What could be the reason for the absence of definition for 'res'?

As I work on coding a bot using discord.js, I am facing an issue while trying to set up a system where the bot can send a message as long as it is not blacklisted. However, every time I attempt to run the function, I encounter this error message: Reference ...

Ways to conceal components upon clicking a different element

Struggling to make this jQuery function properly. I have a form with all fields contained in a div.form-group. The subscribe button is identified by the id subscribe. I'm aiming to hide the form fields when clicked, but my JavaScript doesn't see ...

Effective HTML element placement with CSS styling

My HTML code includes a form containing a table. Take a look: This is the Code I'm Using: <html> <head></head> <body> <form onsubmit="" id="form1" action="" method="post" name="form1" style="position: rela ...

Loop through each item in order to modify the text within the pop-up using a for loop

Goal Upon clicking a .player, a popup should display with relevant data about that player fetched from players.js Issue: When clicking on a player, the event seems to trigger multiple times instead of just once. This results in retrievi ...

Show ng-message when email is invalid in Angular Material without using ng-pattern

I need to show an error message that says Please enter valid email. when an invalid email is entered, but I cannot use the ng-pattern attribute with this specific regex pattern. <md-input-container class="md-block" flex-gt-xs> <label>Ema ...

Steps to verify if a value is an integer:

Lately, I've been working on a "spinner" that increments and decrements a number by 1 each time. However, I'm struggling to add validation to the program so that it only accepts integers (no decimals). I've tried looking into NaN and parseVa ...

Ways to automatically style the child divs within a parent div

I'm trying to figure out how to float a parent div with child divs of different widths and heights while maximizing the use of space and not being affected by absolutely positioned elements. For reference, here's an example: http://jsfiddle.net ...

Angular: Assigning a key from one variable to a value in another

I am currently facing a challenge with rendering a form on a page using ng-repeat, where the data for this form is dynamically fetched from a request. Within this data, there is a nested array called "categories" which contains IDs. I want to display the n ...

Creating a CSS full-width navigation menu

Recently, I came across a menu code on the web that seemed great. However, I wanted to make my menu responsive and full width. Since I am new to CSS and HTML, adjusting the menu code has been a bit of a challenge for me. .menu, .menu ul { list-style: ...