It's in development or being considered by other browsers. See chromestatus. Scrolling is one of the most fundamental ways to interact with a page, but certain UX patterns can be tricky to deal with because of the browser's quirky default behaviors.
As an example, take an app drawer with a large number of items that the user may have to scroll through. When they reach the bottom, the overflow container stops scrolling because there's no more content to consume. In other words, the user reaches a "scroll boundary". But notice what happens if the user continues to scroll. The content behind the drawer starts scrolling!
Scrolling is taken over by the parent container; the main page itself in the example. Turns out this behavior is called scroll chaining ; the browser's default behavior when scrolling content. Oftentimes the default is pretty nice, but sometimes it's not desirable or even unexpected.
Certain apps may want to provide a different user experience when the user hits a scroll boundary. Pull-to-refresh is an intuitive gesture popularized by mobile apps such as Facebook and Twitter. Pulling down on a social feed and releasing creates new space for more recent posts to be loaded. In fact, this particular UX has become so popular that mobile browsers like Chrome on Android have adopted the same effect. Swiping down at the top of the page refreshes the entire page:.
For situations like the Twitter PWAit might make sense to disable the native pull-to-refresh action. In this app, you probably don't want the user accidentally refreshing the page. There's also the potential to see a double refresh animation! Alternatively, it might be nicer to customize the browser's action, aligning it more closely to the site's branding.
The unfortunate part is that this type dhan ki paniri customization has been tricky to pull off. These workarounds have well-documented negative effects on scrolling performance. The overscroll-behavior property is a new CSS feature that controls the behavior of what happens when you over-scroll a container including the page itself. The best part is that using overscroll-behavior does not adversely affect page performance like the hacks mentioned in the intro!
Let's dive into some examples to see how to use overscroll-behavior. Consider a fixed positioned chatbox that sits at the bottom of the page. The intention is that the chatbox is a self-contained component and that it scrolls separately from the content behind it. However, because of scroll chaining, the document starts scrolling as soon as the user hits the last message in the chat history.
For this app, it's more appropriate to have scrolls that originate within the chatbox stay within the chat. We can make that happen by adding overscroll-behavior: contain to the element that holds the chat messages:.
Essentially, we're creating a logical separation between the chatbox's scrolling context and the main page. Scrolls that start in the chatbox do not propagate out. Another variation of the "underscroll" scenario is when you see content scrolling behind a fixed position overlay. A dead giveaway overscroll-behavior is in order! The browser is trying to be helpful but it ends up making the site look buggy. Example - modal with and without overscroll-behavior: contain :.
Turning off the pull-to-refresh action is a single line of CSS.GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together. If nothing happens, download GitHub Desktop and try again. If nothing happens, download Xcode and try again. If nothing happens, download the GitHub extension for Visual Studio and try again.
Lethargy does not have external dependencies. Lethargy is used in smartscrolla jQuery scroll plugin, to resolve problems with inertial scrolling. Create an instance of Lethargy. You may pass in options see belowbut usually the default is good enough. If you found optimizations for the defaults, please share it in this ticket! Lethargy focus on preventing false positives saying it's a normal scroll event when it wasn'tbut tolerates false negatives saying it's not a normal scroll event when it is.
If you are using Webpack, you can use the exports-loader to require the Lethargy constructor. In effect, the larger the value, the smoother the curve will be. This attempts to prevent anomalies from firing 'real' events. Valid values are all positive integers, but in most cases, you would need to stay between 5 and around Because the tail of the curve have low wheelDelta values, this will stop them from registering as valid scroll events.
The unofficial standard wheelDelta isso valid values are positive integers below Valid values are decimals from 0but should ideally be between 0. Scroll plugins such as smartscrolljquery-mousewheel or fullPage.
However, inertial scrolling continues to emit scroll events even after the user stopped, and this can often lead to problems, such as scrolling two to three frames when the user only scrolled once. Below charts the wheelDelta values of each scroll action using this Gist and demo by Matthew Simpson. Lethargy keeps a record of the last few wheelDelta values that is passed through it, it will then work out whether these values are decreasing decayingand if so, concludes that the scroll event originated from inertial scrolling, and not directly from the user.
Not all trackpads work the same, some trackpads do not have a decaying wheelDelta value, and so our method of decay detection would not work. Instead, to cater for this situation, we had to, grudgingly, set a very small time delay between when events will register. We have tested this and for normal use does not affect user experience more than usual.
Skip to content. Dismiss Join GitHub today GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together. Sign up. CoffeeScript Hello C-kick thanks for the good work which saved me from this trouble, I have a small problem with this though and that is any clickable elements inside the element with class inertialScroll will ignore the click event!!!
Skip to content. Instantly share code, notes, and snippets. Code Revisions 1 Stars 10 Forks 1. Embed What would you like to do? Embed Embed this gist in your website. Share Copy sharable link for this gist. Learn more about clone URLs. Download ZIP. Otherwise use quotes. Note: if the finger leaves this listener while still touching, movement is stopped. Devices with larger screens take longer durations phone vs tablet is around ms vs ms.
This is a fixed value and does not influence speed and amount of momentum. Higher values will allow faster scroll which comes down to a bigger offset for the duration of the momentum scroll note: touch motion determines actual speed, this is just a limit. The multiplier is used to multiply the offset. Set to 0 to disable. This is based on a quartic 'out' curve.
This comment has been minimized. Sign in to view. Copy link Quote reply. Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window.
The dark mode beta is finally here. Change your preferences any time. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. I understand that there have to be two timestamps at the beginning of the scrolling at the end. There also has to be an "axis change" variable which is basically the amount to scroll by without inertia. Is it possible to calculate an " inertia addition " for that? Like an additional offset gained by inertia which I can scroll by in addition to the primary scroll value.
Or do I need to get additional variables? If you store say the last half a second of changes with the corresponding timestamps, you can then test if the queue is longer than a value N ie if the user dragged it quicker than usual towards the end. You know the total distance traveled in the last half a second, the time, from those you can get a speed.
Scale the speed to something reasonable say. When the speed reaches 0 or goes below it kill the timer. On each mouse drag event or touch eventyou store the velocity so the amount of movement divided by the time since the last frame and a timestamp.
You only need the last one, so that's just two variables. If so, set a variable inertialVelocity to the last calculated velocity; otherwise set it to 0 to prevent scrolling if the user carefully selected a position. You'll probably want to add a threshold, so scrolling stops if inertialVelocity becomes too small.
I use 1 as a threshold, as my rendering lib uses floats as coordinates. If coordinates are integrals, it'll drop to zero by itself. One thing to keep in mind is that inertialVelocity can be either positive or negative, depending on the direction. Learn more. Ask Question. Asked 8 years, 11 months ago. Active 4 months ago. Viewed 5k times. How would I calculate the scrolling momentum for a scroll event? I need this because I'm writing my own UI toolkit, which isn't really based on anything.
Linus Juhlin 5 5 silver badges 23 23 bronze badges. Kristina Brooks Kristina Brooks What GUI toolkit are you using? How does intertia relate to scolling? I know that this is a GUI effect used for smooth scrolling and for touch scrolling.
Please supply this information, to enhance the question. Also this is not really a C question. Voted to close because to vague. I'm not using a GUI toolkit, I'm making it. Active Oldest Votes. You could simulate this with a "recent axis changes" queue.Compared with a regular linear scroll, momentum scrolling offers a more natural way of scrolling that is easier on the eye and a lot more graceful.
I was frustrated by this when creating a simple web-app base layer recently. It hooked into touch events using a library, TouchSwipe to enable horizontal swiping, or navigating, within the webapp.
For vertical swiping, I wanted my content to scroll. I could have just detected a vertical scroll, and set a stopPropagation ; to resume default browser behavior and enabling momentum scrolling, but that did not cut it: I wanted to only scroll the element I wanted to scroll, and leave other things like the body and document static ; if the user would swipe on anything but scrollable elements, I wanted my content to stay in place by default, a rubber band effect will occur when scrolling past the end of a page for example, I did not want that to happen.
So I bound the vertical touchmove events to do a scrollTop on the element so it would scroll. Happy times; this worked fine. Hoewever, this did not look as pretty as the momentum scrolling that most touch-based devices produce. As I could not enable this native behaviour see aboveI needed to add some kind of simulated momentum scrolling. This was a lot more work than I expected.
I first tried out various pre-built solutions by others, like Droidscroll and jQuery. I have tried numerous methods for simulating momentum scrolling, and after a fair amount of experiments finally settled on the following principle, based on three touch events:.
To my amazement, this produced very nice results, and after some tweaking I managed to get pretty close to native momentum scrolling. At least; good enough for me. Click here for a demoor scroll the code example further below. Be sure to view it on a touch-enabled device or use debug tools to override and emulate touch with your mouse, like in the Chrome developer tools.
Below is the full annotated code for the inertial scroller at the time of writing. Paste it into a. The code should be non-unobtrusive and thus should not wreck any existing touch based handlers but I am by no means a jQuery expert, so try it out for yourself.
Feel free to modify and adapt the code a mention would of course be nice.
I […]. This was just what I was looking for. For me the e. Great work and many thanks! I gather you did not read any of what I wrote above, as I address both the usage cases as the side effects. Great work! Momentum scrolling using jQuery. Click here. The idea I have tried numerous methods for simulating momentum scrolling, and after a fair amount of experiments finally settled on the following principle, based on three touch events: touchstart — get the coordinates of the touch event and store them, create a timer for the start time touchmove — calculate distance by comparing the coordinates of the touch event to the coordinates stored on touchstart and calculate acceleration or speed of the touch movement by dividing distance by current time — start time.
In the meantime scroll the element.
Demo Click here for a demoor scroll the code example further below. Code Below is the full annotated code for the inertial scroller at the time of writing. Otherwise use quotes. Note: if the finger leaves this listener while still touching, movement is stopped. Devices with larger screens take longer durations phone vs tablet is around ms vs ms.
The dark mode beta is finally here. Change your preferences any time. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information. Using a MacBook trackpad I am getting different behaviours: Chrome and Safari work as I would expect, continuing the inertia after going back to the top.
Firefoxhowever, goes back to the top and stops the inertia. Using iOS Safari a similar issue appears too, as the scrollTop position is not updated until the inertia finishes. Is there a better way of approaching it or a way to fix desktop Firefox and iOS Safari behaviour?
Well, it should be an issue with iOS. Please check these resources below for more information first. My experience in the past is to use a library named iScroll and then you can apply its function scrollTo. However, the inertia that is induced by the trackpad cannot be stopped because it is not controlled by the browser. Depending on the device type mouse wheel, trackpad or operating system Windows, OSX and browser type Chrome, Safari, Firefoxthe inertia of the scroll will be handled differently.
Smooth Scroll With Inertia Support – scrooth
You may try to circumvent it or create an artificial one, but you cannot go against the user trackpad.
I have a div with scrollable content that at a certain scrollTop value goes back to top. Linus Juhlin 5 5 silver badges 23 23 bronze badges. Alvaro Alvaro 6, 7 7 gold badges 36 36 silver badges 63 63 bronze badges.
Provided fiddle working fine on firefox Using trackpad, in your Firefox it continues with the inertia it had when it comes to the Top instead of just stopping as it happens to me? Active Oldest Votes. Using a library to handle smooth scroll would help at some point. Simon Simon 1, 5 5 silver badges 19 19 bronze badges.
Sasuke91 Sasuke91 86 7 7 bronze badges. Sign up or log in Sign up using Google. Sign up using Facebook. Sign up using Email and Password.I'd like to be able to tell the difference between real events and the others I found a solution that works really well for this. Below is some pasted code from my project. It basically comes down to this logic:. Since Mac spams scroll events with descreasing delta's to the browser every 20ms when inertial scrolling is enabled, this is a pretty failsafe way.
I've never had it fail on me at least. Just checking the time since the last scroll won't work because a user won't be able to scroll again if the "virtual freewheel" is still running even though they haven't scrolled for 3 seconds.
There's one caveat by the way: Mac also has acceleration on the scrolling, i. It seems like this does not last more than ms or so though.
I had a big problem with an object animating based on scroll position after the scroll had completed, and the inertial scroll was really messing me around. I ended up calculating the velocity to determine how long the inertial scroll would last and used that to wait before animating.
To make situation worse, this editor is embedded in page that has its own scroll bar, because its bigger than one screen. U use overflow-x scroll for horizontal scroll, but for vertical scroll i need current line highlighter as seen in most modern IDEs so i'm using jquery mousewheel plugin, and scrolling moving content for line height up or down. Even still, sometimes on Mac listener on mac wrapper doesn't prevent default, and page scrolls down.
Fun, right? One thing that you can continually detect, however, is window. That value will keep changing while an inertial scroll is happening but won't throw an event.
So you can come up with a set of timers to keep checking for an inertial scroll and keep running itself until the page has stopped moving. It basically comes down to this logic: A scroll event is from a human when ANY ONE of these conditions are true: The direction is the other way around than the last one More than 50 milliseconds passed since the last scroll event picked ms to be sure The delta value is at least as high as the previous one Since Mac spams scroll events with descreasing delta's to the browser every 20ms when inertial scrolling is enabled, this is a pretty failsafe way.
I cant even describe how much annoying that is. There's a library that solves this problem. Yes and no. Tricky stuff, but it should work.