111

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.

2
  • Please take a look at my answer on smooth scrolling with plain js Commented Jul 18, 2013 at 19:07
  • 8
    simplest: onclick="window.scrollTo({ top: 0, behavior: 'smooth' });" Commented Jul 16, 2018 at 10:36

16 Answers 16

219

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> 
Sign up to request clarification or add additional context in comments.

4 Comments

Not all. Not supported in IE 11 and below, no support in Safari or Safari iOS. Check out the full list here. caniuse.com/#feat=css-scroll-behavior
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');
@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.
Remember smooth scroll works only if you have enabled animations in Windows. (not sure about other OS)
89

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.

4 Comments

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;
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.
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?
The cleanest solutions would be using window.scrollTo({ top: 0, behavior: 'smooth' }) with adding smoothscroll-polyfill @AkankshaMohanty
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.

Comments

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">

4 Comments

:* This is Awesome
@hemnathmouli Thanks
Doesn't seem to work for me. Have added text to the 'Your text here' part. The button jumps you back to the top
@user2840467 its working fine. I checked in chrome and mozilla. Can you please describe your problem in details.
7

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

Comments

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.

8 Comments

Well first of all, I have no idea how to use jQuery and javascript - here's the code from the second link which I persume will work if only I can connect it to the <a href> hyperlink. $('html, body').animate({ scrollTop: $("#elementID").offset().top }, 2000);
Oh, I take that back, I realize it also links to an element, which would probably require an anchor.
if you already have jQuery, then just do $("body").animate({scrollTop:0});
been trying hundreds of variations but nothing seems to give me what i need. i guess i'll just link it to the top of the body which i am allowed to edit
Sorry for the confusion, but I shouldn't have posted the menu bar along with it because that too has its own css and java codes included. The only things that matter in my fiddle are the two <sript src's and the <a class="smoothScroll". Maybe I should open a new question page.
|
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>

Comments

5

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>

2 Comments

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.
Ok this function scroll up to the Top of Page and is smooth.
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/[email protected]"></div>

Comments

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/[email protected]/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>

Comments

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

Comments

1

If you're using an anchor element to scroll to the top of the page and it's jumping straight to the top without the smooth transition, remove the href="#" attribute.

<a onclick="smoothScrollToTop()"></a> <script> function smoothScrollToTop() { window.scrollTo({ top: 0, behavior: 'smooth' }); } </script> 

Comments

0

also used below:

 document.body.scrollTop = 0; document.documentElement.scrollTop = 0; 

Comments

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

Comments

0
$('html,body').animate({ scrollTop: 0 }, 'slow'); 

Just like that, Simple & Clean...

Comments

-1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.