97

I've bean searching for this for a few hours now and I have no solution. I want a smooth scroll to the top of the page. I already have smooth scrolling to separate anchors in the page with a .js file attatched to my site but I cannot use an anchor for the top, because I'm using a template from a free hosting site with built in page building tools that do not allow me to edit above the body area.

Here's where I got the smooth scrolling. I've been trying to set up "smoothly-scroll-to-an-element-without-a-jquery-plugin" but I have no idea how to arrange it obviously after countless attempts. I've also used window.scrollTo(0, 0); but it scrolls instantly. Thanks!

In addition: http://jsfiddle.net/WFd3V/ - the code would probably be the tag class="smoothScroll" since my other element uses that, but I don't know how to mix it with the href="javascript:window.scrollTo(0,0);" , or anything else that would bring the page to the top without an anchor.

Danubian Sailor
  • 1
  • 38
  • 145
  • 223
user2267388
  • 979
  • 1
  • 6
  • 4
  • Please take a look at my answer on [smooth scrolling with plain js](http://stackoverflow.com/questions/17722497/scroll-smoothly-to-specific-element-on-page/17731750#17731750) – surfmuggle Jul 18 '13 at 19:07
  • 7
    simplest: onclick="window.scrollTo({ top: 0, behavior: 'smooth' });" – vukan Jul 16 '18 at 10:36

15 Answers15

197

I think the simplest solution is to use window.scrollTo:

window.scrollTo({top: 0, behavior: 'smooth'});

If you wanted instant scrolling then just use:

window.scrollTo({top: 0});

Can also be wrapped in a function:

// Scroll To Top
function scrollToTop() {
    window.scrollTo({top: 0, behavior: 'smooth'});
}

Or used as an onclick handler:

<button onclick='window.scrollTo({top: 0, behavior: "smooth"});'>
   Scroll to Top
</button>
KyleMit
  • 30,350
  • 66
  • 462
  • 664
theMaxx
  • 3,756
  • 2
  • 27
  • 33
  • 1
    Not all. Not supported in IE 11 and below, no support in Safari or Safari iOS. Check out the full list here. https://caniuse.com/#feat=css-scroll-behavior – tomastley Aug 20 '19 at 17:55
  • 1
    This doesn't work on Chrome too. It triggers an error that ScrollTo requires 2 arguments and only 1 passed. I fixed it using jQuery and: `$('html, body').animate({scrollTop:0},'50');` – Ivica Pesovski Dec 06 '19 at 13:41
  • 2
    @IvicaPesovski You probably didn't put your arguments within an object. `scrollTo` want's to have only one argument that is either a number or an object. If you choose to pass an object, then you can specify the `behavior`. This solution works fine for me on Chrome / Electron. – Martin Braun Aug 14 '20 at 16:02
85

Here is my proposal implemented with ES6

const scrollToTop = () => {
  const c = document.documentElement.scrollTop || document.body.scrollTop;
  if (c > 0) {
    window.requestAnimationFrame(scrollToTop);
    window.scrollTo(0, c - c / 8);
  }
};
scrollToTop();

Tip: for slower motion of the scrolling, increase the hardcoded number 8. The bigger the number - the smoother/slower the scrolling.

Milkncookiez
  • 6,817
  • 10
  • 57
  • 96
Gor
  • 1,385
  • 12
  • 7
  • Nice solution thank you. But in IE11 scrollTop value does not going below the 8/2 and if you scroll down again it keeps scrolling up continuously I made some changes and added these lines: `const smoothness = 8; let val = s - s / smoothness; if (val < smoothness) val = 0; window.scrollTo(0, val);` The problem is gone but it has little jump effect due to `val = 0;` – fatihsolhan May 12 '19 at 12:56
  • Script with a nice effect but in conflict with the CSS rule `scroll-behavior: smooth`, the CSS rule must be disabled for the duration of the script. – Olivier C Jun 09 '20 at 22:41
  • yes In IE the solutions doesn't work properly as mentioned by @Solhan. the solution which is given by sohan also didn't work for me. Is there any other solution that will work properly in IE? – Akanksha Mohanty Dec 18 '20 at 10:26
  • The cleanest solutions would be using `window.scrollTo({ top: 0, behavior: 'smooth' })` with adding [smoothscroll-polyfill](https://www.npmjs.com/package/smoothscroll-polyfill) @AkankshaMohanty – fatihsolhan Dec 19 '20 at 11:09
28
window.scroll({top: 0, behavior: "smooth"})

Just use this piece of code and it will work perfectly, You can wrap it into a method or event.

Leonel Kahameni
  • 793
  • 8
  • 10
12

Pure Javascript only

var t1 = 0;
window.onscroll = scroll1;

function scroll1() {
  var toTop = document.getElementById('toTop');
  window.scrollY > 0 ? toTop.style.display = 'Block' : toTop.style.display = 'none';
}

function abcd() {
  var y1 = window.scrollY;
  y1 = y1 - 1000;
  window.scrollTo(0, y1);
  if (y1 > 0) {
    t1 = setTimeout("abcd()", 100);
  } else {
    clearTimeout(t1);
  }
}
#toTop {
  display: block;
  position: fixed;
  bottom: 20px;
  right: 20px;
  font-size: 48px;
}

#toTop {
  transition: all 0.5s ease 0s;
  -moz-transition: all 0.5s ease 0s;
  -webkit-transition: all 0.5s ease 0s;
  -o-transition: all 0.5s ease 0s;
  opacity: 0.5;
  display: none;
  cursor: pointer;
}

#toTop:hover {
  opacity: 1;
}
<p>your text here</p>
<img id="toTop" src="http://via.placeholder.com/50x50" onclick="abcd()" title="Go To Top">
Bhuwan
  • 16,525
  • 5
  • 34
  • 57
Nikhil sHETH
  • 510
  • 4
  • 11
6

Hmm comment function off for me,

try this

$(document).ready(function(){
    $("#top").hide();
    $(function toTop() {
        $(window).scroll(function () {
            if ($(this).scrollTop() > 100) {
                $('#top').fadeIn();
            } else {
                $('#top').fadeOut();
            }
        });

        $('#top').click(function () {
            $('body,html').animate({
                scrollTop: 0
            }, 800);
            return false;
        });
    });         
            
            
    
    });
#top {
  float:right;
  width:39px;
  margin-top:-35px; 
}
#top {
    transition: all 0.5s ease 0s;
    -moz-transition: all 0.5s ease 0s;
    -webkit-transition: all 0.5s ease 0s;
    -o-transition: all 0.5s ease 0s;
    opacity: 0.5;
    display:none;
    cursor: pointer;
}
#top:hover {
    opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />
<div id="top" onclick="toTop()"><img src="to_top.png" alt="no pic "/> klick to top</div>
BitDEVil2K16
  • 326
  • 3
  • 11
  • 2
    Welcome to Stack Overflow! Please consider editing your post to add more explanation about what your code does and why it will solve the problem. An answer that mostly just contains code (even if it's working) usually wont help the OP to understand their problem. It's also recommended that you don't post an answer if it's just a guess. A good answer will have a plausible reason for why it could solve the OP's issue. – SuperBiasedMan Dec 14 '15 at 09:09
  • 2
    Ok this function scroll up to the Top of Page and is smooth. – BitDEVil2K16 Dec 14 '15 at 15:13
6

Some time has passed since this was asked.

Now it is possible to not only specify number to window.scroll function, but also pass an object with three properties: top, left and behavior. So if we would like to have a smooth scroll up with native JavaScript, we can now do something like this:

let button = document.querySelector('button-id');
let options = {top: 0, left: 0, behavior: 'smooth'}; // left and top are coordinates
button.addEventListener('click', () => { window.scroll(options) });

https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll

Akimbas
  • 163
  • 1
  • 5
5

You should start using jQuery or some other js lib. It's way easier than js, and you can use it as a shorthand for most js instead of actually long, drawn out js.

Simply put <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> (or whatever the latest google cdn is https://developers.google.com/speed/libraries/devguide#jquery) in your <head>.

Then, inside your event code (much easier if you use jQuery: $.click() for buttons, $.change() for checkboxes, selects, radios...), put the code from your second link looking more like

$('#theIDofTheButtonThatTriggersThisAnimation').click(function(){
    $('#theIDofTheElementYouWantToSmoothlyScroll').animate({
        scrollTop: 0
    }, 2000);
});

However, if you're trying to do animations, I recommend you look into some basic css properties like position:absolute and position:relative to keep from going crazy.


I'm still not quite sure what's going on in your code because it's very non-standard relative to how things are done now with css & jQuery. I'd break it down into something simple to learn the general concept.

For your example, you should build off of my animation example, how I learned: https://stackoverflow.com/a/12906254/1382306

I think you're trying to move your text up and down based upon a $.click(). In the fiddle in my answer, it slides left and right. You can easily reformat up and down by using the css top property instead of left.

Once you figure out how to move the entire div up and down, you can make a relative container to hold all of the content absolute divs and manipulate all content divs with a loop by setting their tops. Here's a quick primer on absolute in relative: http://css-tricks.com/absolute-positioning-inside-relative-positioning/

All of my animations have relative containers and absolute content. It's how I made a custom gridview plugin that can instantly zip through an entire database.

Also, there really is no overuse of divs when it comes to animating. Trying to make 1 div do everything is a nightmare.

Try to see if you can reformat my fiddle into a vertical slide out. Once you've done that, research absolute in relative a little. If you have any more problems, just ask another question.

Change your thinking to these philosophies, and you'll start flying through this type of coding.

Community
  • 1
  • 1
5

You can simply use

// When the user scrolls down 20px from the top of the document, show the button
window.onscroll = function() {scrollFunction()};

function scrollFunction() {
    if (document.body.scrollTop > 20 || document.documentElement.scrollTop > 20) {
        document.getElementById("gotoTop").style.display = "block";
    } else {
        document.getElementById("gotoTop").style.display = "none";
    }
   
}

// When the user clicks on the button, scroll to the top of the document
function topFunction() {
 
     $('html, body').animate({scrollTop:0}, 'slow');
}
body {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 20px;
}

#gotoTop {
  display: none;
  position: fixed;
  bottom: 20px;
  right: 30px;
  z-index: 99;
  font-size: 18px;
  border: none;
  outline: none;
  background-color: red;
  color: white;
  cursor: pointer;
  padding: 15px;
  border-radius: 4px;
}

#gotoTop:hover {
  background-color: #555;
}
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>

<button onclick="topFunction()" id="gotoTop" title="Go to top">Top</button>

<div style="background-color:black;color:white;padding:30px">Scroll Down</div>
<div style="background-color:lightgrey;padding:30px 30px 2500px">This example demonstrates how to create a "scroll to top" button that becomes visible when the user starts to scroll the page.</div>
Waruna Manjula
  • 3,067
  • 1
  • 34
  • 33
4

Elegant easy solution using jQuery.

<script>
    function call() {
        var body = $("html, body");
        body.stop().animate({scrollTop:0}, 500, 'swing', function() {
        });
    }
</script>

and in your html : <div onclick="call()"><img src="../img/arrow-up@2x.png"></div>

Ron16
  • 445
  • 6
  • 11
3

For a more comprehensive list of methods for smooth scrolling, see my answer here.


To scroll to a certain position in an exact amount of time, window.requestAnimationFrame can be put to use, calculating the appropriate current position each time. setTimeout can be used to a similar effect when requestAnimationFrame is not supported. To scroll to the top of the page, the following function can be called with position as 0.

/*
   @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);
        }
    });
}

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);
        }
    });
}

window.scrollTo(0, 2000);
document.querySelector('button').addEventListener('click', function(e){
  scrollToSmoothly(0, 700);
});
<button style="margin: 2000px 0;">Smooth scroll to top</button>

The SmoothScroll.js library can also be used, which handles more complex cases such as smooth scrolling both vertically and horizontally, scrolling inside other container elements, different easing behaviors, scrolling relatively from the current position, and more.

smoothScroll({yPos: 'start', duration: 700});
// or
smoothScroll({yPos: 0, duration: 700});

window.scrollTo(0, 2000);
document.querySelector('button').addEventListener('click', function(e){
  smoothScroll({yPos: 'start', duration: 700});
});
<script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/SmoothScroll@1.2.0/src/smoothscroll.min.js" integrity="sha384-UdJHYJK9eDBy7vML0TvJGlCpvrJhCuOPGTc7tHbA+jHEgCgjWpPbmMvmd/2bzdXU" crossorigin="anonymous"></script>
<button style="margin: 2000px 0;">Smooth scroll to top</button>

Alternatively, you can pass an options object to window.scroll with behavior set to smooth, which scrolls to a specific x and y position, or window.scrollBy which scrolls a certain amount from the current position:

// Scroll to specific values
// scrollTo is the same
window.scroll({
  top: 2500, 
  left: 0, 
  behavior: 'smooth' 
});

// Scroll certain amounts from current position 
window.scrollBy({ 
  top: 100, // could be negative value
  left: 0, 
  behavior: 'smooth' 
});

window.scrollTo(0, 2000);
document.querySelector('button').addEventListener('click', function(e){
  window.scroll({top: 0, left: 0, behavior: 'smooth'});
});
<button style="margin: 2000px 0;">Smooth scroll to top</button>

Modern browsers support the scroll-behavior CSS property, which can be used to make scrolling in the document smooth (without the need for JavaScript).

window.scrollTo(0, 2000);
document.querySelector('button').addEventListener('click', function(e){
  window.scrollTo(0, 0);
});
html, body {
  scroll-behavior: smooth;
}
<button style="margin: 2000px 0;">Scroll to top (JavaScript)</button> 
<a href="#">Link to smoothly scroll to top of page (no JavaScript)</a>
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
2

I just customized BootPc Deutschland's answer

You can simply use

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
    $(document).ready(function(){
        $('body,html').animate({
            scrollTop: 0
        }, 800);
    $('#btn-go-to-top').click(function () {
        $('body,html').animate({
            scrollTop: 0
        }, 800);
        return false;
    });
}); 
</script>

this will help you to smoothly scroll to the top of the page.

and for styling

#btn-go-to-top {
opacity: .5;
width:4%;
height:8%;
display: none;
position: fixed;
bottom: 5%;
right: 3%;
z-index: 99;
border: none;
outline: none;
background-color: red;
color: white;
cursor: pointer;
padding: 10px;
 border-radius: 50%;
}

#btn-go-to-top:hover {
opacity: 1;
}
.top {
transition: all 0.5s ease 0s;
-moz-transition: all 0.5s ease 0s;
-webkit-transition: all 0.5s ease 0s;
-o-transition: all 0.5s ease 0s;
}

this styling makes the button arrive at the bottom-right of the page.

and in your page you can add the button to go to top like this

<div id="btn-go-to-top" class="text-center top">
<img src="uploads/Arrow.png" style="margin: 7px;" width="50%" height="50%">
</div>

hope this help you.if you have any doubts you are always free to ask me

vichu
  • 353
  • 2
  • 10
1

also used below:

  document.body.scrollTop = 0;
  document.documentElement.scrollTop = 0;
Kapil Soni
  • 1,003
  • 2
  • 15
  • 37
0

Came up with this solution:

function scrollToTop() {
let currentOffset = window.pageYOffset;
const arr = [];

for (let i = 100; i >= 0; i--) {
    arr.push(new Promise(res => {
            setTimeout(() => {
                    res(currentOffset * (i / 100));
                },
                2 * (100 - i))
        })
    );
}

arr.reduce((acc, curr, index, arr) => {
    return acc.then((res) => {
        if (typeof res === 'number')
            window.scrollTo(0, res)
        return curr
    })
}, Promise.resolve(currentOffset)).then(() => {
    window.scrollTo(0, 0)
})}
Keks
  • 11
  • 2
0

theMaxx answer works in nuxt/vue, smooth scrolling is default behavior

<button @click=scrollToTop()>Jump to top of page

  methods: {
    scrollToTop() {
      window.scrollTo({ top: 0 });
    }
  }
atazmin
  • 4,757
  • 1
  • 32
  • 23
0
$('html,body').animate({ scrollTop: 0 }, 'slow');

Just like that, Simple & Clean...

Eyni Kave
  • 1,113
  • 13
  • 23