I'm currently in the middle of building out a proof-of-concept for InVision that uses a flexbox layout with some "overflow:auto" scrollable areas. And, as I've been coding this feature, I've noticed that the Chrome browser occasionally stops responding to the scroll wheel on my Logitech Mouse. At first, I thought maybe this was an issue in the way I was using flexbox. But, when I tried to switch from flexbox to "position:absolute", the problem persisted. As it turns out, this is a known bug in Chrome. I wanted to share this problem (and a video of the reproduction steps) in case it was driving anyone else nuts. It's not your fault. It's a browser bug.
In the discussion forum linked above, people state that this happens with any Chrome tab; however, I personally have only experienced the issue with an overflow container - not with the parent page. That said, here is the demo code for the reproduction, as seen in the above video:
As you can see, I have some "overflow: auto" containers, one using flexbox and one using "position: absolute". I'm also logging the "wheel" and "scroll" events (using the capture phase of the event life-cycle). These two events should go hand-in-hand as long as there is content to scroll. However, it is not that hard to reproduce a case in which the "wheel" indicates an "UP" event, but there is no corresponding "scroll" event (because Chrome isn't scrolling the overflow container):
As you can see, I can easily get to a point where I am moving the mouse wheel up and down and I am seeing no subsequent scrolling of the overflow container. Then, if I pause for a second or two, and try the mouse wheel again, things will start working as expected.
So, this is a Chrome bug. It's not your fault.
Hopefully this helps maintain the sanity of anyone else who runs into this problem. And, if you have any suggestions on how to work-around the bug, please let us know!
Want to use code from this post? Check out the license.
So, Sean Roberts - head of the Web Performance here at InVision - has a good theory about this behavior. He believes that the browser is trying to figure out which container is supposed to be receiving the scroll event. As you may know, when you scroll in the browser, it the targeted container runs out of "scrollable content", the browser will start walking up the DOM tree to find parent containers with scrollable content; and, if possible, apply the
wheel event said container. This is why, in the past, I've created an Angular directive trap scrolling in a given container:
But, the theory is, the
wheel event doesn't look like its being applied to the embedded container because the browser is - at that moment - trying to apply it to the
body, which has no scrollable content.
So, the browser is trying to figure out how to provide the best user experience; but, in this case, isn't making the best choice.
So, I went back and played around with the
wheel event. Specifically with preventing the default behavior of the
wheel event when the overflow container runs out of scroll room. And, it appears to have a positive impact on this bug:
It's hard to "prove" that it's fixed. But, what I can say is that I can very easily and consistently reproduce the problem in a "control case"; but, I have yet to reproduce the issue when I intercept and manipulate the
there is a fix here
I wonder if there is a fix that is explained as if it were to a 5 year old? I don't understand anything you all are saying and I am self diagnosed as "Tech-Tarded". Any help is much appreciated.
My attempt at a non-techie answer: Have you have seen someone from across the street and they wave at you. So you wave back; only to realize a moment later that they are actually waving at someone behind you?
That's kind of like what is happening here. When I move my scroll-wheel, it's like I'm "waving" at one of the containers on page. Except, the wrong container is "waving back" (by attempting-and-failing to scroll). And I want to say, "No, not you -- the other guy!"
Not sure if that made any sense :D
I am not sure that approach would work. It looks like it is, essentially, adding a "cover" Div to the entire browser. Because this Div is "fixed" position, and lower in the DOM tree, it would stack above the content before it, making the content inaccessible to clicks and other mouse interactions.
Unless I am missing something obvious.
It seems that adding
overscroll-behavior: none to the overflow containers fixes this. https://developer.mozilla.org/en-US/docs/Web/CSS/overscroll-behavior
OH CHICKENS! This is awesome!! It's not in all the browsers; but it's in Chrome and Firefox! I will definitely be playing around with this a bit more. Outstanding :D
This morning, I did a little experimentation with the
overscroll-behavior CSS property:
This is awesome! Thank you so much for pointing this out to me. This is huge. I'm gonna be shipping changes for this today to my production app.
It was a pretty exciting discovery for me too! Glad it helped.
using will-change: transform fixed scrolling for me
In a Fixed overflow sidebar div with dynamic loaded content that randomly stopped scrolling in Chrome Version 78.0.3904.108
Wow many thanks, can't believe it solved our scroll issue
You might be interested in a follow-up post that uses
overscroll-behavior to "fix" this problem in modern browsers:
could you please go with more information as solution provided by @Knud works extremely fine.
so please let me know the reason why to use overflow behaviour
and what is the advantage of it over will-change property.
At the end of the day, whatever works for you is "good". That said, the reason that I like the
overscroll-behavior option is that it is solving the root problem, rather than simply getting the browser to do what you want. Meaning, the root issue here is that the user-scroll-event is getting sent to the wrong container element (which is why the scrolling stops working). So, when you use
overscroll-behavior, you are explicitly telling the browser how you want the scroll events to be handled. It feels more "correct" to me.
But, that's just my opinion.
I was also having this issue in Chrome 78 and your solution works. Many thanks.
Could you share a refence code for this fix.
It will use full for me.
I saw reference to using "will-change: transform" on a post on stackoverflow to fix some other issue and when I used it, it also seemed to fix my scrolling issue. But whatever I search for now I can't find it again. I only posted here because using overscroll-behavior didn't fix the issue in my situation. I think because the div I needed to scroll was updated via AJAX and was in a Fixed position. I've looked now for half an hour and can't find the post again.
I also tried to find the reference, but i cant. Anyway thank you for your time support. I will try to implement this one "will-change: transform" .
Since Chrome update 79, I can't reproduce that bug anymore... Did the update solve the issue ? What about you guys ?