Prevent scroll bounce for the body element, but keep it for child elements in iOS

Kyle Lacy picture Kyle Lacy · Sep 30, 2012 · Viewed 36.8k times · Source

I've been working on a mobile webapp as of late. I'm optimizing mobile-first, focusing specifically on iOS for the iPhone right now. I don't want the precise look of a native app, but I think that the feeling of being native is of absolute importance. I've made the markup and CSS to reflect this idea, leaving me with this (annotated to better understand the problem I'm having later on):

Webapp markup

This all works problem-free, and it also has the advantage of having a native feel, with static header and footer, and a scrollable inner view (thanks to -webkit-overflow-scrolling: touch).

As anyone who has used iOS for more than 5 minutes will know, when you scroll up or down, you get some nice momentum scrolling. Also, when you hit the top of a list, you get a nice 'bounce' effect:

List bouncing in Settings.app

I feel that this helps to define the feeling of iOS, and such a small detail can go a long way. Luckily, when you are below the top of a list in a scrollable element in a webapp, and scroll past the top, you get the same effect. This is the desired behavior in action:

Scrolling down and up in a webapp produces this bouncing effect

However, when you are at the top of the list, and try to recreate the same bouncing behavior a the top of the list (à la Setting.app, seen above), we get the following behavior, which is not desired: Scrolling down produces the bouncing effect for the entire chrome of the app

I've seen some similar questions on Stack Overflow, but these all opt for disabling bouncing. I'm wondering if it's at all possible to keep bouncing, but always make it occur on body section section#main, not on webapp's chrome. I'm not using jQuery, so I'd prefer answers to be in straight-up JavaScript (bonus points for a CSS solution, though).

Here's a GitHub repo with all of the code (Sinatra, HAML, and Sass; current branch is so), or a JSFiddle with broken images and links, but shows the issue in question on an iPhone (best to add to homescreen to test).

Answer

Samuli Hakoniemi picture Samuli Hakoniemi · Jan 8, 2013

OLD INFO: I've solved this: http://www.hakoniemi.net/labs/scrollingOffset/nonbounce.html

NEW INFO: This is now a jQuery plugin that can be found from here: http://www.hakoniemi.net/labs/nonbounce/.

There are several issues, like losing the zooming capability when this is applied or it's dynamic updating isn't working fluently.

But now the simplest way is to define: <div class="nonbounce">...</div> and then $.nonbounce();