85

So I am desperatley trying to get some scrolling functionality to work on a page. After not having a luck I decide to just stick window.scrollTo(0, 800); on my page to see if I could get any scrolling to happen. Nothing does happen. I have an accordion that expands and then I want to scroll to a specific element with in it. But for now I would be happy to just see the thing scroll at all. Anyone run into this?

Thanks!

Dan McGrath
  • 41,220
  • 11
  • 99
  • 130
Nick
  • 19,198
  • 51
  • 185
  • 312
  • I should note that I have tried the scrollTo JQuery plugin without any luck there as well. $.scrollTo(0,800); – Nick Jul 23 '09 at 22:35
  • 3
    In firefox in my address bar i just put javascript:window.scrollTo(0, 800); and it seemed to work. – Davis Jul 23 '09 at 22:44
  • ok, a. try it in different browsers, see if it works in any. b. try something like document.body.scrollTo. c. remember that javascript is case sensitive. Not sure if any of those will help, but you can try. – Nico Burns Jul 23 '09 at 22:44
  • @luvat You are right! It works in this page but not in mine. I tried it in the address bar just as you did and it works here in S.O. but not in my project. Bazaar. – Nick Jul 23 '09 at 22:58
  • 1
    scrollTo does do something, just not on your page... I'm guessing you will get little help without posting a url, your code, or at least providing some more details about your specific issue. – Prestaul Jul 23 '09 at 22:58
  • This actually another page that is being displayed within an iframe. that must be the problem here. How can I scroll within that frame? – Nick Jul 23 '09 at 23:03
  • 1
    Horrible question. You provide no code, and we have no idea when your code is executing (if at all). – Josh Stodola Jul 23 '09 at 23:09
  • `scrollTo` was disabled for me because of a chrome plugin, not sure which. – Jacksonkr Jul 26 '19 at 17:52

23 Answers23

123

If you have something like this:

html, body { height: 100%; overflow:auto; }

If both body and html have a height definition of 100% and also scrolling enabled, window.scrollTo (and all derived scrolling mechanisms) do not work, despite a scrollbar being displayed (which can be used by the user), when the contents exceed that 100% body height. This is because the scrollbar you see is not that of the window, but that of the body.

Solution:

html { height: 100%; overflow:auto; }
body { height: 100%; }
frevd
  • 1,247
  • 2
  • 8
  • 3
  • 7
    To follow up here (many years later!), if you don't want to change your CSS in this case, you can instead use `document.body.scrollTo({ top: ... })` instead of window.scrollTo. – btown Jul 19 '22 at 12:40
  • @btown thanx for saving my hrs – Navin SK Aug 12 '22 at 13:07
  • @btown thanks but it still doesn't work for me. ` document.body.scrollTo({ behavior: 'auto', left: 0, top: 0, });` does not scroll on top of the page.. – Kristi Jorgji Feb 13 '23 at 10:12
  • @KristiJorgji make sure it's actually the body that is scrolling when you scroll. It's possible you have another height: 100% component inside it that's actually the thing that is scrolling. Feel free to create a new question if you're still having issues! – btown Feb 14 '23 at 18:16
52

I fixed this problem with using a setTimout. I was using angularjs but maybe it can help in vanilla js too.

        setTimeout(function () {
            window.scrollTo(0, 300);
        },2);
Vince Verhoeven
  • 1,693
  • 14
  • 25
29

I was able to resolve this problem using jQuery method animate(). Here is an example of the implementation I went with:

$('#content').animate({ scrollTop: elementOffset }, 200);

The selector is getting the div with ID = "content". I am then applying the animate method on it with scrollTop as an option. The second parameter is the time in milliseconds for the animation duration. I hope this helps someone else.

Nick
  • 19,198
  • 51
  • 185
  • 312
  • 2
    I tried the other answers. This is the only one that worked for me too. Difference is I used `$('body').animate({ scrollTop: top }, 0);` where `top` is the variable containing the y-coordinate in integer. – Kim Stacks Nov 06 '13 at 05:01
  • @KimStacks A duration of 0 didn't work for me, but using 1 did.. can't believe how hard this is to do! – Arth Jul 06 '18 at 16:06
27

Sometimes it's not just the CSS issue, for me the browser was the culprit. I had to solve it with this code:

if ('scrollRestoration' in window.history) {
  window.history.scrollRestoration = 'manual'
}

It lets developer take the ownership of scroll changes. Read more about it here

Daniel_Knights
  • 7,940
  • 4
  • 21
  • 49
Bikal Basnet
  • 1,639
  • 1
  • 21
  • 31
16

This happened to me yesterday because I had overflow: auto on a div that was a child to <html> and <body>.

So I learned that for window.scrollTo() to work, you must have overflow: auto (or whatever, overflow-y: scroll) set on the <html> element.

I learned that for document.body.scrollTo() to work, you must have overflow set on <body>.

I learned you can also use it on any other element (if you want) using document.querySelector('#some-container').scrollTo().

In my case, I wanted window.scrollTo() to work, so I put the overflow CSS on <html>.

I'm surprised no other answers in here talk about "exactly which" element is scrollable. The root html element must be scrollable for window.scrollTo() to work. All my child elements downstream of <html> are set to height: auto.

My CSS is like this:

html { position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: auto; }
body { width: 100%; height: auto; }
#app { width: 100%; height: auto; }
agm1984
  • 15,500
  • 6
  • 89
  • 113
11

I had this same problem.Focusing window before scrollTo worked for me.

window.focus();
window.scrollTo(0,800);
Jeroen Heier
  • 3,520
  • 15
  • 31
  • 32
bth_
  • 111
  • 1
  • 2
6

For me setting the height of html and body to auto did the trick.

html, body { height: auto }
Asim Mahar
  • 1,320
  • 1
  • 10
  • 13
6

TL;DR

document.querySelector('#dummy_element').scrollIntoView()

worked for me.

Explanation

I too was having an issue with the following

document.querySelector('#some-container').scrollTo()

window.scrollTo()

as @agm1984 mentioned here:

I then tried using:document.querySelector('#dummy_element').scrollIntoView()

that worked out for me.

Differences are explained here in a better way.

Quick difference:

Element.scrollIntoView() method scrolls the element on which it's called into the Viewport of the browser window.

Window.scrollTo() method scrolls to a particular set of coordinates in the document.

Jay
  • 641
  • 9
  • 11
5

This is what I do on React, as I have a root element, as the first and outer most div on my page, I scroll to the top of that element.

      const root = document.getElementById('root');
      root.scrollTo({
        top: 0,
        left: 0,
        behavior: 'smooth',
      });
hazimdikenli
  • 5,709
  • 8
  • 37
  • 67
3

I had this problem and it had nothing to do with these answers. The problem for me first appeared after upgrading to Bootstrap 4 which converted a lot of my divs over to display: flex. It turns out JQuery's scrollTop() doesn't work so well with flex layouts.

The solution for me was to change my old code from:

$("#someId").scrollTop(1000);

// or

$("#someId").animate({ scrollTop: 1000 }, 500);

to

$("html,#someId").scrollTop(1000);

// or

$("html,#someId").animate({ scrollTop: 1000 }, 500);

The only difference is adding in the "html," before the div that needs to scroll.

Props to this issue for helping me figure it out.

Ryan Shillington
  • 23,006
  • 14
  • 93
  • 108
3

I was having this same problem today and then I discovered that when I took out the auto generated doctype block:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

The window.scrollTo(0,800) started working along with the ExtJs scrollTo() function I was originally trying to use. I put the block back in and it stopped working. I don't know if this is what you were running into (2 years ago) but hopefully this helps someone else running into the same problem.

Jerry West
  • 31
  • 1
2

In a React app, wrapping window.scrollTo with a setTimeout worked.

useEffect(() => {
  if (scrollPosition > 0) {
    setTimeout(() => window.scrollTo(0, scrollPosition), 0);
    setScrollPosition(0);
  }
}, [scrollPosition]);
vijayst
  • 20,359
  • 18
  • 69
  • 113
1

check if your tag where is plugged your scroll get a CSS overflow[/-x-y] : hidden. it fixed the bug

marcdahan
  • 2,654
  • 25
  • 25
1

In my case: window.scrollBy(0,200); is working.

I have no idea WHY window.scrollTo(0,200); is not working and window.scrollBy(0,200); is working.

Ahmad Sayeed
  • 344
  • 2
  • 14
1

document.body.scrollTo(0, 800) This solved my issue.

1

If for some reason both

   html,body {overflow: hidden}

have to be set, you could still scroll programatically with:

   document.body.scrollTop = document.body.scrollHeight; // scrolls to bottom
   document.body.scrollTop = 0; // scrolls to top
Milan Dala
  • 384
  • 2
  • 5
0

First, is you page even big enough to scroll (even if it's in an iframe)? If not, or you aren't sure, make a giant div, then put something below it. Try scrolling to that.

Next, if your scrolling in an iframe, put your code on the same page as the frame source. That way you don't have to worry about getting the document or specific element in the other window, which can be tricky. Oh yeah, are you sure you are getting that part right? Stepping through with Firebug can help you with that.

Finally, put a breakpoint (using Firebug) on the line that is supposed to cause the scrolling to happen. Does it hit that breakpoint? If not, your code is not executing, and scrolling is not your problem.

(I answered this, with supporting context from your earlier question.)

EDIT:

Scrolling is done window by window. If you are in a frame that can't scroll, then nothing will scroll. If you want that element in the frame to be scrolled to, get the offset of that element to its current window and add it to the offset of the containing frame. That should do the trick.

Community
  • 1
  • 1
geowa4
  • 40,390
  • 17
  • 88
  • 107
  • Yes, the page has enough height. I can see the scroll bar. I suspect that the problem has to do with the composition of this page. Because this site was created before the days of masterpages I have a main page that contains 2 frames. The first is a header nav bar and the other is a content area. I am assuming that this is the reason that the scrollTo method doesn't seem to work. – Nick Jul 24 '09 at 14:55
  • yeah, scrolling is done window by window. if you are in a frame that can't scroll, then nothing will scroll. and you will go crazy trying to figure out what's wrong. oh... – geowa4 Jul 24 '09 at 15:49
0

If the scrolling has been done after a slide down, it should wait for the div to complete the animation like this

$('#div-manual-lots').slideDown(200, function () { $("html, body").animate({ scrollTop: $(document).height() }, 1000) });

Saaram
  • 337
  • 3
  • 7
  • 29
0

Using the onunload property worked for me

window.onunload = function(){ window.scrollTo(0,0); }
Rami Nour
  • 2,035
  • 1
  • 14
  • 11
0

In my case I had a js function "scrollTo" with same name ... :O Renaming fixed my problem.

robie2011
  • 3,678
  • 4
  • 21
  • 20
0

Try set html tag:

html {
  height: auto;
  overflow: auto;
}

It works for me.

borchvm
  • 3,533
  • 16
  • 44
  • 45
-2

When window.scrollTo(x,y) does not work on the console of the Browser, and the dom gets rendered after scroll, you can use this.

To scroll on Splash or any javascript rendering service execute below js:

document.body.style.height = "2000px";
window.scrollTo(0,2000);

In Splash you can do something similar to this:

  assert(splash:wait(10))
  assert(splash:runjs("document.body.style.height = '2000px';"))
    assert(splash:runjs("window.scrollTo(0,2000);"))
  assert(splash:wait(2))
  assert(splash:runjs("window.scrollTo(0,0);"))
Rajan
  • 1,463
  • 12
  • 26
-4

Take this code: http://www.java2s.com/Code/JavaScriptReference/Javascript-Methods/scrollToExample.htm and save as an html file. Note how it hard codes a very large div larger than the browser's viewport. You probably need to add a content at the bottom of your page for the scrolling to even work.

Christopher Tokar
  • 11,644
  • 9
  • 38
  • 56