Title Image generated with DALLE2
Pull to refresh is a convenient way for users to refresh a page. It started in mobile apps like twitter and got adapted by mobile browsers pretty soon.
When building an SPA which should feel native pull to refresh can also be pretty annoying and make users accidentally refresh the page. That's why we want to prevent it sometimes.
There exists many hacks out there. Some of them are more inversive and will cause side effects. For example, a preventDefault
on a touchMove
event. Even when executed on single divs, it will prevent all touchMove
events on this div. This workaround will prevent pull to refresh, but it will also prevent lots of other functionalities like scrolling a Dialog etc.
A better way is to find a CSS only solution that will tell the browser how to behave only for specific scroll actions.
The actions we are talking about are called overscroll-behaviour.
What is Overscroll-behaviour
Overscroll, or more specific overscroll-behavior describes what the browser should do when reaching the top, or bottom of a page.
There are three different values to define the overscroll-behaviour.
Auto, contain and none.
overscroll-behavior: auto, as you might already guess, is the default behavior. It will give us the well known bounce effect when reaching the top or bottom of a scrollable element. For whole pages it will, may trigger a refresh, what we want to prevent.
overscroll-behavior: contain, is similar to auto, the main difference is that scroll chaining is disabled. This means for short that we can scroll the target element and get the bounce effects, but when reaching the top or the bottom we will not scroll further.
overscroll-behavior: none, there are no effects, no bouncing and no other things when reaching the end of the scroll box. When reaching the top or the bottom, it will just stop and do nothing else. Nothing else, also means no pull to refresh! That's exactly what we want to achieve!
So overscroll-behavior: none is the way to go for us.
How to prevent overscroll
As mentioned above, we can prevent it by using overscroll-behavior: none.
This will simply deactivate all the scrolling side effects we do not want to happen. The only downside is that we are losing the bounce animation when reaching the end of our scroll box. So it will feel a little more paper like.
How to prevent pull to refresh
Okay now we have learned a lot about overscroll, let's not combine this to prevent pull to refresh.
To prevent pull to refresh on safari and all other browsers, we need to apply overscroll-behavior: none
on the HTML element.
<style>
html {
overflow: hidden;
overscroll-behavior: none;
}
</style>
How to prevent pull to refresh in vue.js
As you may know, I’m obsessed with Vue. But sometimes it can be a special snowflake too.
The above solutions were not working for my projects out of the box, and I was wondering why. It worked for plain HTML test projects, but implemented in my vue app, it was not working — WTF!
First I thought the reason might be some overwrites somewhere, but that was not
After some educated trial and error, I found out.
When we want to apply CSS to our HTML, we want to do it directly. The overscroll behavior, was defined in a scoped style tag.
According to the vue documentation:
When a
<style>
tag has thescoped
attribute, its CSS will apply to elements of the current component only. This is similar to the style encapsulation found in Shadow DOM.
So the only thing we need to do is, place it in a normal style tag and make sure that it is not in a scoped tag even when targeting HTML. Otherwise, the changes will have no effect.
So the solutions was to simply place the above snippet into a standard style tag.
Done! Amazing! Our users will love this!
<style>
html {
overflow: hidden;
overscroll-behavior: none;
}
</style>
Thank you for reading!
I hope this short guide was able to solve this problem for you.
Happy coding,
Alex