Form elements can lose click hit area in position: fixed containers #1

scottjehl opened this Issue Mar 23, 2012 · 13 comments


None yet


  • Android 2.x
  • iOS5

How to reproduce:

  1. Place a form element inside a fixed-positioned container. (button, input, select, etc)
  2. Programatically scroll the page, using window.scrollTo or scrollBy
  3. Buttons will not react to touch/tap until the page is manually scrolled

Note: double-tapping the control does work in iOS5

Reduced Example:

Bug Tracker ticket(s):


None known.


I found something that seems similar - my touch events were no longer triggered on buttons in a fixed position header after I manually scrolled.

Here's my touch code:

For some reason adding a touchstart event to body fixed it:
$('body').bind('touchstart', function(e) {

I don't understand why, unfortunately.


Thanks, @pamelafox. Think that warrants a separate issue? @wilto filed issue #3 on Android fixed position bugs, which have some iOS5 overlap too I think.

Wilto commented Mar 29, 2012

@pamelafox: I would be frightened for you if you could fully understand Android’s position: fixed bugs. It’s a disaster.

@scottjehl: I’ll go in and split those up into separate properly-formatted issues later on today, methinks.


Found a great fix for iOS. Simply add a div triggering scrolling to the end of the document (a height of 101% should work) then create a setTimeout with a delay of 0 to remove the div. This will cause iOS to recalculate the hit position of fixed area elements


+1 to the strange fix by pamelafox. Was facing the same issue on manual scroll and have been racking my brains for quite a while. You just saved my life.
Any ideas on why it works? Maybe like kentongray's solution it forces iOS to recalculate position of fixed div elements?

robtarr commented Jun 7, 2012

I have a fixed position button with a click handler. I tried Pamela's solution but it didn't work in this case.


I was able to work around this basically by doing the opposite of what kentongray did.

We have a fixed header with buttons, and are showing/hiding divs. Whenever we show/hide divs, we call ScrollView to reset our window to the top position. If we did this while the screen was scrolled down (not already in top position), the buttons would stop responding until a manual scroll was performed. But if the window was at the top position when we called ScrollView, the bug didn't happen.

We got around this by changing the order of events. We hide the main div we're about to take away, then we call ScrollView, THEN we show our new main div. When performed in this order, our buttons always continue working. It seems that hiding the main view shortens the view into the size of the window, which somehow prevents the bug.

Hope that helps someone.

rprieto commented Jun 20, 2012

@jaredthigpen it definitely helped me, cheers!

I had very similar symptoms (the fixed div not responding to clicks, or jumping to the middle of the page), and like you it didn't happen if the page was already scrolled to the top - and get back to normal after a manual scroll. It's a single page web-app, so the code looked like:


After spending hours trying everything else (101% height divs, empty handlers...), your suggestion worked like a charm:


I wish I had seen your post or thought about it earlier!


I too have a button that is fixed at the bottom and I couldn't get position:fixed; to stay at the bottom on Android 2.x until I added the following:

$('#docked-nav').css('-webkit-transition', '-webkit-transform 0.5s').css('-webkit-transform', 'translateX(0px)');

Don't ask me why it works, it's a lucky guess :)

The button doesn't respond to tap once scrolled though. @pamelafox fix did not work for me.

sebumd commented Jul 25, 2012

@rprieto Where did you put that code? $('body').scroll?

rprieto commented Jul 26, 2012

@sebumd For me the problem happened when scrolling while "changing page". Since it's a single-page web app, changing page is really custom code that changes the visibility of certain DIVs:

function changePage(target) {
    window.scrollTo(0,0);  // Go back to the top
    $('section.current').removeClass('current');   // Hide the current div
    $(target).addClass('current');   // Show the new div instead

// When the user clicks to see the third tab

So now it looks like:

function changePage(target) {
    window.scrollTo(0,0);  // Do this while all "pages" (divs) are hidden

I hope it's a bit clearer.


I faced the same problem: I had a fixed positioned header having a back button.
When the page is programatically scrolled, the click event of back button stopped working.
My workaround was same as the above:

$(document.bind('silentscroll', function(e,data){
window.scrollTo(0, newPos);



Here is a way around the bug without a hack.

Instead of having the mobile site scroll in the body, disable body scrolling, set height to 100%, and then use a container div for the scrolling instead. This way the fixed elements are outside of the scrollable area, making them immune to this bug.

I tried all the hack solutions out there, but all of them had this bug. Only after separating the fixed elements and the scroll area was the issue fixed.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment