iOS Safari Fix for Form Elements Inside Position Fixed Divs Receiving Input

iOS Safari jumps to the top of the page when form elements inside fixed positioned divs receive input.


I set up a demo of this behavior (please make sure to test it on an iOS device :)).
Ooops, seems like position:fixed does not work inside iframes either. The fixed navbar just get scrolled out of the viewport. I’m sure, you have a demo of the problem somewhere working. That’s why you are here, right?

Observed Behavior

When the input or select receives focus, the page jumps to the top, the navbar is animated a little bit down and jumps back to top. Furthermore the tab bar is shown when its hidden by default which does not make any sense to me. Luckily, there is a quick fix by adding the following css to the <html> and <body> elements.

Fixed with CSS

html,
body {
    -webkit-overflow-scrolling : touch;
    overflow: auto;
    height: 100%;
} 

Check out this pen to see the fix applied.

Other options

If You can’t use this fix for whatever reasons you still have some options:

  • Don’t use form elements inside position fixed divs
  • Hack some JavaScript to prevent the scrolling or to update the scroll position
  • Throw even more JavaScript on it and use a position sticky polyfill or another polyfill
  • Wait for position:sticky to arrive in iOS

Conclusion

Personally I try to avoid using position fixed at all. I don’t see how the user experience is enhanced by elements hanging here and there around. If you need to nag someone to login or register or buy something then it’s a great tool. Ah wait. Big pages like amazon, google, etc. don’t use position fixed elements. Hmmm. I’m sure they have very good reasons.

5 Replies to “iOS Safari Fix for Form Elements Inside Position Fixed Divs Receiving Input”

  1. Sorry, but the header menu follows the scroll up on my iPad (iOS9). I am facing the same issue with “position:fixed” on my own project. iOS seems to be failing to apply it properly.. Really annoying :(

  2. Thanks for sharing your solution but I found a major problem.

    html,
    body {
    -webkit-overflow-scrolling : touch;
    overflow: auto;
    height: 100%;
    }

    Unfortunately, this css fix stops the js event ‘scroll’ from being fired. The combination of all three somehow prevents scroll events from firing.

    ie:
    $(window).scroll(function() {
    console.log(‘window.scroll’);
    });

    This js will NEVER fire and you will not get any console log no matter how much you scroll.

    This is a big problem. I’m trying to find another fix or maybe modify this fix.

Comments are closed.