Skip to main content
Ben Nadel at CFinNC 2009 (Raleigh, North Carolina) with: Zeljka Majetic
Ben Nadel at CFinNC 2009 (Raleigh, North Carolina) with: Zeljka Majetic ( @zeljkaNYC )

Chrome Browser Bug: Scroll Wheel Randomly Stops Working In Overflow Container

By on

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.

Run this demo in my JavaScript Demos project on GitHub.

View this code in my JavaScript Demos project on GitHub.

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:

<!doctype html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<title>
		Chrome Browser Bug: Scroll Wheel Randomly Stops Working In Overflow Container
	</title>

	<style type="text/css">

		html {
			box-sizing: border-box ;
		}

		*, *:before, *:after {
			box-sizing: inherit ;
		}

		/* BEGIN: Layout-A - It uses FLEXBOX and Overflow. */
		.layout-a {
			border: 2px solid #cccccc ;
			display: flex ;
			flex-direction: column ;
			height: 500px ;
			margin: -250px 0px 0px 0px ;
			position: absolute ;
			right: 51% ;
			top: 50% ;
			width: 300px ;
		}

		.layout-a__top-panel {
			flex: 1 1 auto ;
			overflow: auto ;
		}

		.layout-a__bottom-panel {
			border-top: 1px solid #cccccc ;
			flex: 0 0 auto ;
			height: 100px ;
			padding: 20px 20px 20px 20px ;
		}
		/* END: Layout-A. */

		/* BEGIN: Layout-B - It uses POSITION ABSOLUTE and Overflow. */
		.layout-b {
			border: 2px solid #cccccc ;
			height: 500px ;
			left: 51% ;
			margin: -250px 0px 0px 0px ;
			position: absolute ;
			top: 50% ;
			width: 300px ;
		}

		.layout-b__top-panel {
			bottom: 100px ;
			left: 0px ;
			overflow: auto ;
			position: absolute ;
			right: 0px ;
			top: 0px ;
		}

		.layout-b__bottom-panel {
			border-top: 1px solid #cccccc ;
			bottom: 0px ;
			height: 100px ;
			left: 0px ;
			padding: 20px 20px 20px 20px ;
			position: absolute ;
			right: 0px ;
		}
		/* END: Layout-B. */

		.content p {
			margin: 0px 0px 0px 0px ;
			padding: 25px 20px 22px 20px ;
		}

		.content p:nth-child( even ) {
			background-color: #f0f0f0 ;
		}

	</style>
</head>
<body>

	<h1>
		Chrome Browser Bug: Scroll Wheel Randomly Stops Working In Overflow Container
	</h1>

	<!-- BEGIN: Layout-A. -->
	<section class="layout-a">
		<div class="layout-a__top-panel">

			<div class="content">
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
			</div>

		</div>
		<div class="layout-a__bottom-panel">

			Using <strong>Flexblox</strong>

		</div>
	</section>
	<!-- END: Layout-A. -->

	<!-- BEGIN: Layout-B. -->
	<section class="layout-b">
		<div class="layout-b__top-panel">

			<div class="content">
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
				<p>Content</p>
			</div>

		</div>
		<div class="layout-b__bottom-panel">

			Using <strong>Position Absolute</strong>

		</div>
	</section>
	<!-- END: Layout-B. -->

	<script type="text/javascript">

		// Theoretically, the "wheel" event and the "scroll" event should go hand-in-hand
		// as long as there is room to scroll the content of a container. However, in
		// Chrome, the scrolling of the mouse-wheel will suddenly stop working (at least
		// as of Chrome/70.0.3538.102). In that case, we can see the "wheel" event being
		// logged without a corresponding "scroll" event.

		window.addEventListener(
			"wheel",
			function handleWheelEvent( event ) {

				var direction = ( event.deltaY >= 0 )
					? "DOWN"
					: "UP"
				;

				console.log( "Event: wheel,", direction, event.target );

			},
			true
		);

		window.addEventListener(
			"scroll",
			function handleScrollEvent( event ) {

				console.log( "Event: scroll" );

			},
			true
		);

	</script>

</body>
</html>

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

Chrome browser bug - scrolling stops working in overflow containers, even though wheel event is still being registered.

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.

Good Will Hunting - 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.

Reader Comments

15,674 Comments

@All,

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:

www.bennadel.com/blog/3365-prevent-scrolling-in-a-parent-element-using-directives-in-angular-4-4-6.htm

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.

15,674 Comments

@All,

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:

www.bennadel.com/blog/3544-trapping-the-wheel-event-may-prevent-chrome-browser-bug-in-which-the-scroll-wheel-stops-working-in-overflow-container.htm

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 wheel event.

1 Comments

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.

15,674 Comments

@Jimmy,

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

15,674 Comments

@Haroon,

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.

15,674 Comments

@Derek,

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

2 Comments

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

1 Comments

@Ben Nadel
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.

15,674 Comments

@Srishti,

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.

2 Comments

@Rajeshkumar,

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.

2 Comments

@knud
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" .

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel