How do I stop my fixed navigation from moving like this when the virtual keyboard opens in Mobile Safari?

69,979

Solution 1

http://dansajin.com/2012/12/07/fix-position-fixed/ this is one of the solutions proposed. Seems worth a shot.

In short: set fixed elements to position:absolute when any input is focused and reset them when that element is blurred

.header { 
    position: fixed; 
} 
.footer { 
    position: fixed; 
} 
.fixfixed .header, 
.fixfixed .footer { 
    position: absolute; 
} 

and

if ('ontouchstart' in window) {
    /* cache dom references */ 
    var $body = $('body'); 

    /* bind events */
    $(document)
    .on('focus', 'input', function() {
        $body.addClass('fixfixed');
    })
    .on('blur', 'input', function() {
        $body.removeClass('fixfixed');
    });
}

Solution 2

The solutions on the top are some ways to go and fix the problem, but I think adding extra css class or using moderniz we are complicating things.

If you want a more simple solution, here is a non-modernizr non-extra-css but pure jquery solution and work on every device and browsers I use this fix on all my projects

if ('ontouchstart' in window) {
    $(document).on('focus', 'textarea,input,select', function() {
        $('.navbar.navbar-fixed-top').css('position', 'absolute');
    }).on('blur', 'textarea,input,select', function() {
        $('.navbar.navbar-fixed-top').css('position', '');
    });
}

Solution 3

I had a similar problem, but I found a workaround by adding the following css class to the body element on input focus and then removing it again on unfocus:

.u-oh {
    overflow: hidden;
    height: 100%;
    width: 100%;
    position: fixed;
}

Solution 4

Taking from what sylowgreen did, the key is to fix the body on entering the input. Thus:

$("#myInput").on("focus", function () {
    $("body").css("position", "fixed");
});

$("#myInput").on("blur", function () {
    $("body").css("position", "static");
});

Solution 5

Add javascript like this:

$(function() {
  var $body;
  if ('ontouchstart' in window) {
    $body = $("body");
    document.addEventListener('focusin', function() {
      return $body.addClass("fixfixed");
    });
    return document.addEventListener('focusout', function() {
      $body.removeClass("fixfixed");
      return setTimeout(function() {
        return $(window).scrollLeft(0);
      }, 20);
    });
  }
});

and add class like this:

.fixfixed header{ 
    position: absolute; 
} 

you can reference this article: http://dansajin.com/2012/12/07/fix-position-fixed/

Share:
69,979
Eric
Author by

Eric

Web designer and front end developer in the greater Philadelphia area.

Updated on July 09, 2022

Comments

  • Eric
    Eric almost 2 years

    I understand that mobile safari has a lot of bugs around fixed elements, but for the most part I've managed to get my layout working correctly until I added a much needed text input to the fixed navigation at the bottom. Now when the user focuses on the text input element and the virtual keyboard appears, my navigation, which is otherwise always fixed at the bottom of the page, jumps up to a really strange spot in the middle of the page.

    enter image description here

    I'd add some of my code to this post, but I wouldn't be sure where to start. That navigation is fixed at the bottom and positioned to the left and bottom 0, and 100% width. From there, I don't know what's going on, I can only assume it's a mobile safari bug.

    It also appears to lose it's position fixed and become relative, only while the text input element is focused on and the virtual keyboard is open.

  • theunexpected1
    theunexpected1 over 10 years
    Ah, that was an easy and smart trick. Thanks for sharing, worked for me.
  • Martin Klasson
    Martin Klasson over 10 years
    Dan Sajin website does not take care of the problem in Chrome-browser on IOS-devices. But it works really well for Safari.
  • Marvin Danig
    Marvin Danig almost 10 years
    What css does the class u-fixedFix contain? This is not working on my iPad (On iOS 7.1.2 - 11D257) as of now.
  • Patrick Canfield
    Patrick Canfield almost 10 years
    The same rules as the class used in the answer by wxy112233, ie. position: absolute.
  • Joe Corby
    Joe Corby over 9 years
    This was one of the simplest fixes I've found that works the best universally. Nice job!
  • VK Chikkadamalla
    VK Chikkadamalla almost 8 years
    bfred plese see this link stackoverflow.com/questions/38341941/…
  • VK Chikkadamalla
    VK Chikkadamalla almost 8 years
    i am also trying to fixed the header when focusing text field but we are not resolving the issue
  • Nearpoint
    Nearpoint almost 8 years
    great simple solid solution :) Just add [contenteditable] to the targets if you have contenteditable divs
  • Matt
    Matt almost 8 years
    This works but causes the header to flash every time the keyboard pops up.
  • jetlej
    jetlej over 7 years
    The other solutions left my footer halfway hidden below the keyboard AND scrolled the whole screen to the very bottom, but this worked perfectly!
  • Stradosphere
    Stradosphere about 7 years
    This is the closest solution so far for me, none of the others seem to work. This one works for me, but sometimes the input is left docked at the bottom and the virtual keyboard overlaps it.
  • Hassan Baig
    Hassan Baig about 4 years
    Just to clear it conceptually, why are height:100%;width:100% needed?
  • JB Wilson
    JB Wilson over 2 years
    I've been searching for days for a solution, and this one worked for me in my react app.