Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Smooth scroll into view not working in >= Chrome 52 #28

Closed
pastelsky opened this issue Jun 8, 2016 · 51 comments
Closed

Smooth scroll into view not working in >= Chrome 52 #28

pastelsky opened this issue Jun 8, 2016 · 51 comments

Comments

@pastelsky
Copy link

The smooth scroll behaviour doesn't take affect for scrollIntoView in chrome 52 for some reason.
The behaviour is fine for scrollBy and other functions though.

Tested on http://iamdustan.com/smoothscroll/

@jeremenichelli
Copy link
Collaborator

Can you specified better what's the behavior or error in console you see? Just tested in Chrome 53 and it works just fine in the demo page. Also, remember the current version of Chrome is 51 so higher version could still have bugs.

@pastelsky
Copy link
Author

There are no console errors. scrollIntoView works but there is a jump, i.e. the smooth behaviour does not work. I'm testing on Chrome 53.0.2761.2 canary (64-bit) OSX

@jeremenichelli
Copy link
Collaborator

jeremenichelli commented Jun 11, 2016

I'm on Chrome 53.0.2765.0 canary (64-bit) OSX and works perfect on both examples from the demopage. Please remember that those are dev build versions from Chrome so it's normal to find bugs on their side. Current version of Chrome is 51 right now http://googlechromereleases.blogspot.com.ar/2016/06/stable-channel-update_6.html and is where the polyfill should work well.

@phloe
Copy link
Contributor

phloe commented Sep 29, 2016

I'm also experiencing this behavior in Chrome (Version 53.0.2785.143 (64-bit)) on OSX - both on the demo page and in a project I'm working on. :(

Looks like the test whether to polyfill or not bails because Chrome already supports it: https://github.com/iamdustan/smoothscroll/blob/master/src/smoothscroll.js#L14
... even though it doesn't support the "smooth" behavior yet. (http://caniuse.com/#feat=scrollintoview)

This is the pain of polyfilling experimental features I guess...

@jeremenichelli
Copy link
Collaborator

@rasmusfl0e I'm on the same Chrome version and OS and the demo page works.

@raaffc-old
Copy link

I dont see this working too in Chrome 58.0.3029.110 (64-bit). It just jumps to the element position but smooth does not work.

elem.scrollIntoView({ behavior: 'smooth'});

@trytriangles
Copy link

This is an issue in Chrome itself.

@sntran
Copy link

sntran commented Aug 17, 2017

Does not work in Chrome 60.0.3112.101 (Official Build) (64-bit) either. While it is an issue in Chrome, shouldn't this polyfill take care of it until the new Chrome version is released?

@fwitkowski
Copy link

in Chrome 61 (Version 61.0.3163.100 (Official Build) (64-bit)) scrollIntoView({ behavior: 'smooth' }) scrolls to middle of element, not to the top. Without behavior smooth (with auto) it works fine.

@jeremenichelli
Copy link
Collaborator

jeremenichelli commented Oct 11, 2017

@fwitkowski that's actually the native implementation of the spec from Chrome. You can force the polyfill to override the native implementation if you want it to work in the same way as Firefox.

#85

@fwitkowski
Copy link

Thanks Jeremenichelli, how can I overwrite this behavior?

@jeremenichelli
Copy link
Collaborator

@fwitkowski 👉 https://github.com/iamdustan/smoothscroll#force-polyfill-implementation

@fwitkowski
Copy link

fwitkowski commented Oct 19, 2017

@jeremenichelli , I tried your suggestion and sitll - different behavior in chrome and firefox. Even in that demo page (http://iamdustan.com/smoothscroll/), if you try clicking SCROLL INTO VIEW in chrome and firefox, you'll see the difference.
In FireFox: https://www.screencast.com/t/QrdPVo5Y2
In Chrome: https://www.screencast.com/t/JwiCMulSyy

@jeremenichelli
Copy link
Collaborator

The demo page is not forcing the polyfill implementation, so it's gonna behave differently. If you could provide an isolated case where the forcing implementation feature doesn't work it would help us analyze what's happening.

@fwitkowski
Copy link

Check this example in jsfiddle: https://jsfiddle.net/fwitkowski/jp5Lc6sv/1/
Code is copied from your demo with added forcing code: window.forceSmoothScrollPolyfill = true;

Compare behavior in chrome and firefox.
PS. I see there is issue with jsfiddle what hides its navigation (this we can ignore)

@jeremenichelli
Copy link
Collaborator

This is not an issue on the library, as the README states the global flag needs to be set to true before the library runs or the module is required, since the override happens over runtime.

From the README:

place this global variable before requiring the module or including the polyfill file

Also, jsfiddle doesn't let you override window variables directly so it's not an ideal environment for this test case.

@jeremenichelli
Copy link
Collaborator

If really wanna see that this works, the best way is to download the repo, and add the flag on the index.html before the script and try it in Chrome.

@thinkloop
Copy link

It does not work on Version 63.0.3239.132 (Official Build) (64-bit) macOS as of this writing.

An easy way to test is to run this in your console and see if it scrolls the page to the top:

document.getElementsByTagName('body')[0].scrollIntoView({ behavior: 'smooth' })

If you omit the options it works again (non-smoothly):

document.getElementsByTagName('body')[0].scrollIntoView()

@jeremenichelli
Copy link
Collaborator

@thinkloop and everyone here, there are some inconsistencies between Chrome and Firefox implementations. The polyfill can't selectively override methods, it just runs or not.

Right now, running document.body.scrollIntoView with smooth scroll behavior enable does nothing in Chrome, while it scrolls to top in Firefox. First thing we need to do is to see if the specs says something about this and choose whatever is the correct behavior.

That said, the scripts throws an error when called the method with those arguments so it's definitely a bug that we will take care of.

In the mean time if you want to scroll to top you can run:

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

This will work in all browsers consistently.

Thanks everyone for reporting ❤️

@thinkloop
Copy link

thinkloop commented Feb 8, 2018

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

Thanks for the workaround, that helps my specific case.

First thing we need to do is to see if the specs says something about this and choose whatever is the correct behavior.

If you use an unsupported value and not "smooth" it displays an error message. It seems like at minimum specifying "smooth" should scroll to the top, whether smoothly or not, next option is showing an error, doing nothing seems like the least optimal behavior.

@jeremenichelli
Copy link
Collaborator

Sorry @thinkloop I didn't expressed myself well, or used the wrong words. What I meant was that when scrolling into view the body element both browsers do different stuff, probably because the spec doesn't specify any behavior at all around that case.

@thinkloop
Copy link

thinkloop commented Feb 8, 2018

This is interesting, I did a few other tests and it seems that if an element consumes the whole viewport or more, it does not scroll, while if any part of the viewport is not consumed, it will scroll to the top of the element - try this from the very bottom of this github page, then from mid-way down the page:

document.getElementsByClassName('application-main')[0].scrollIntoView({ behavior: 'smooth' })

To be clear there is still a bug here: that 'smooth' does not work consistently to non-smooth. Whatever logic is decided upon, the smooth option should do exactly as the non-smooth option, just with smoothness or not. Right now they behave differently. If you try the above code without the smooth, u will see it will always scroll to top.

@jeremenichelli
Copy link
Collaborator

Totally. I think I've never tried the polyfill with an element occupying more space than the viewport, I will take this as part of the fix and see what I find. Thanks for the suggestions and insights.

@dietergeerts
Copy link

Using group.scrollIntoView({behavior: "smooth"}); does not work, while group.scrollIntoView(); does. Chrome Version 65.0.3325.181 (Official Build) (64-bit)

@jeremenichelli
Copy link
Collaborator

@dietergeerts what is group a list of nodes? an element? Can you open a new issue with a reduced case that we can debug? Thanks in advance.

@dietergeerts
Copy link

'group' is one html element. I'll see if I can create a live case to test. The code is on a work project.

@matthew-ia
Copy link

Disclaimer: I'm not using iamdustan's smooth scroll polyfill, but I ran into this same problem with vanilla javascript in Chrome, and found this Issue (and not much else) in my search for a solution. This fix seems to be working consistently for me.

My fix was to use preventDefault() in order to get the smooth behavior to work. I was having weird and inconsistent behavior with other element scroll functions as well, but this seemed to help me out with all of the variations of element.scroll() I had tried. Here's a look at my code:

handleSmoothScroll(e) {
    let id = e.target.parentNode.getAttribute("href").slice(1,); // Gets the id for the element I want to scroll to
    document.getElementById(id).scrollIntoView({
      behavior: "smooth"
    });
    e.preventDefault(); // This is very necessary so the normal anchor snapping doesn't occur.
  }

I am using Chrome 68.0.3440.106 on macOS. My fix (under my circumstances at least) works in Firefox 61.0.2 as well. Hopefully this helps someone.

@Laurensdc
Copy link

Laurensdc commented Sep 26, 2018

I found that passing block and inline arguments makes the function work in Chrome.

top.scrollIntoView({ behavior: 'smooth' });

The above doesn't work, while the code below does.

top.scrollIntoView({
  behavior: 'smooth',
  block: 'start',
  inline: 'nearest'
});

@TurnInToReality
Copy link

@Laurensdc Thanks. Your suggestion worked for me.

@madhavan-sundararaj
Copy link

Is there any way to make the smooth transition from scrollIntoView quite faster, right now it works fine but if there is any possibility to speed up the smooth transition, it will be very helpful. Thanks in Advance

@ogostos
Copy link

ogostos commented Apr 1, 2019

Is there any way to make the smooth transition from scrollIntoView quite faster, right now it works fine but if there is any possibility to speed up the smooth transition, it will be very helpful. Thanks in Advance

I guess it's not possible with current implementation.

@YummyLucky
Copy link

YummyLucky commented Nov 2, 2019

chrome version 78.0.3904.70(正式版本) (64 位)
I found that when I use el.scrollIntoView({ block: 'center', behavior: 'smooth' }) and document.querySelector('.someScrollElement').scrollTop = aNumber; at the same time, the scrollIntoView not work.
el & someScrollElement are not the same thing

@imvikaskohli
Copy link

document.querySelector('.className).scrollIntoView({behavior: "smooth"}); -> not working
document.querySelector('.className).scrollIntoView(); -> working

Similarly for the Viewchild reference

this.scroll.nativeElement.scrollIntoView({block: 'end', behavior: "smooth"})-> not working
this.scroll.nativeElement.scrollIntoView({behavior: "smooth"})-> not working
this.scroll.nativeElement.scrollIntoView() -> working

@Bettaswamy
Copy link

document.querySelector(target).scrollIntoView();
document.querySelector(target).scrollIntoView({ behavior: 'smooth'});

Tried both the ways in chrome Version 81.0.4044.138(official-build). but no luck, smooth scroll is not working

@madhavan-sundararaj
Copy link

document.querySelector(target).scrollIntoView();
document.querySelector(target).scrollIntoView({ behavior: 'smooth'});

Tried both the ways in chrome Version 81.0.4044.138(official-build). but no luck, smooth scroll is not working

Try putting it inside a setTimeout, it worked for me in that way.

@MadaShindeInai
Copy link

MadaShindeInai commented Jun 4, 2020

Try putting it inside a setTimeout, it worked for me in that way.

foo.scrollIntoView({ behavior: 'smooth', block: 'center' }); ----> old
Do not scroll anything at all.

setTimeout(() => foo.scrollIntoView({ behavior: 'smooth', block: 'center' }), 0); -----> new
Tryed, it's really start scrolling but in in 70% of cases position that scrolls - incorrect.
Anyone knows solution? And i think it`s problem appear cuz of last chrome update?

@robert-gyori
Copy link

@MadaShindeInai are scrolling on events?
Apply touch-action: none; on the html element and e.preventDefault(); in your callback

@ianrockefeller
Copy link

Providing a solution that worked for me with the caveat that it requires jQuery so could be ported to vanillaJS:

// before
foo.scrollIntoView({ behavior: 'smooth' });

// after
$('html, body').animate({
    scrollTop: $(foo).offset().top
}, 200);

@mikeaustin
Copy link

After 4 years, this still doesn't seem to work...

This works every single time, without a timeout, called with react-animate-height onAnimationEnd:

elementRef.current.scrollIntoView(true)

This doesn't scroll as expected. It seems to even scroll in the opposite direction:

elementRef.current.scrollIntoView({
  behavior: 'smooth',
  block: 'start',
  inline: 'nearest',
});

I've also tried using CSS scroll-behavior: smooth, which has the same problems as the above method.
I'd expect that it scrolls to the same location whether animated or not.

@shehrozsheikh
Copy link

shehrozsheikh commented Sep 19, 2020

Changing behavior to behaviour worked for me in Chrome.

@leocavalcante
Copy link

It worked for me after I switch this option to active:

image

@dietergeerts
Copy link

@leocavalcante , but then we are dependant on the user to have this setting on as developers, which really is not good.

@leocavalcante
Copy link

@dietergeerts if the user don't want to see it animated/smooth, why you should force it to be? ¯_(ツ)_/¯

@dietergeerts
Copy link

@leocavalcante , because it can contribute to a better UX, and if we would use it, and the user has the option turned off, then the site or app will look badly done.

@hakimio
Copy link

hakimio commented Oct 7, 2020

If you are using Angular and want to add smooth "scroll into view" functionality to your project which works on any browser and doesn't depend on Windows visual effects configuration, I would recommend ngx-smooth-scroll.

@GregoryR13
Copy link

Try putting it inside a setTimeout, it worked for me in that way.

foo.scrollIntoView({ behavior: 'smooth', block: 'center' }); ----> old
Do not scroll anything at all.

setTimeout(() => foo.scrollIntoView({ behavior: 'smooth', block: 'center' }), 0); -----> new
Tryed, it's really start scrolling but in in 70% of cases position that scrolls - incorrect.
Anyone knows solution? And i think it`s problem appear cuz of last chrome update?

It didn't work for me on "document.ready" but ok on other event.
For Chrome, on load document :

setTimeout(function () {
foo.scrollIntoView({behavior: 'smooth', block: "center"});
}, 100);

@jmengere
Copy link

I still have the same problem. Was it resolved?

@hakimio
Copy link

hakimio commented Dec 16, 2020

@jmengere see this comment: #28 (comment)

@Alesich
Copy link

Alesich commented Oct 20, 2022

Still have this problem, #28 (comment) - doesn't work for me

@GundaSudarrshan
Copy link

GundaSudarrshan commented Mar 4, 2023

Yeah still facing ScrollIntoView() problem, how to fix it, I am unable to implement in basic Vanilla Js also.
any suggestions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests