Prevent iOS Safari Scroll Bounce (Rubber-Band Effect) with CSS
I was testing the mobile sidebar for a new client project yesterday. Everything looked perfect on Android. But when I opened it on my iPhone and swiped to the bottom of the menu, the entire webpage yanked upwards. It revealed a blank gray background behind the DOM.
That classic iOS Safari rubber-band effect. It makes custom web apps feel cheap and broken.
Years ago, we handled this by writing massive JavaScript event listeners to intercept and block touchmove events. It was a nightmare. It broke native scrolling momentum and hurt accessibility. Fortunately, Safari on iOS 16+ finally caught up with modern CSS specifications. You don't need JS hacks anymore.
The one-line CSS solution
The fix is entirely handled by the overscroll-behavior property. This property tells the browser what to do when it reaches the boundary of a scrolling area.
To kill the bounce effect globally across your entire webpage, apply it to the root elements. Open your main stylesheet and add this:
overscroll-behavior-y: none;
}
I specifically target the y axis here. Using overscroll-behavior: none disables it for both X and Y. Usually, you only want to stop the vertical pull-to-refresh and bottom bounce, while leaving horizontal swipe gestures intact.
Fixing specific scrollable containers (Modals & Sidebars)
Sometimes you don't want to lock the whole page. Maybe you just have a scrollable popup modal or a navigation drawer. When a user reaches the bottom of the modal, iOS passes the scroll event to the background body, causing the whole page behind the modal to slide around. This is called scroll chaining.
To trap the scroll exactly inside your container and prevent it from leaking out, apply it directly to your wrapper class:
height: 100vh;
overflow-y: auto;
overscroll-behavior: contain;
}
Notice I used contain instead of none here. This tells Safari: "Keep the bounce effect inside this specific box if you want, but absolutely do not let the background page move."
Troubleshooting iOS Quirks
Apple's WebKit engine can be stubborn. If you apply the CSS and the page still bounces, check this quick matrix of edge cases I run into frequently.
| The Problem | The Quick Fix |
|---|---|
Still bouncing on the body tag |
Ensure your html tag isn't set to height: 100%. It conflicts with viewport boundaries. |
| Pull-to-refresh is broken | If you used none, pull-to-refresh dies. Change it back to auto if you need native refreshing. |
| Only fails on old iOS 15 devices | iOS 15 and below do not fully support this CSS. You have to fallback to position: fixed on the body wrapper. |
Drop those old JavaScript prevent-default scripts into the trash. The CSS approach is faster, utilizes the GPU better, and keeps your Core Web Vitals perfectly intact.