38

I'm having a problem with a div element to stick to the bottom of my web app when ios 7 virtual keyboard appears after pressing a textbox.

I've this div element:

....
        <div id="footer" style="text-align:center">
            <div id="idName"><img alt="SomeName" src="images/logo.png" /></div>
        </div>

    </form>
</body>

It uses this style

#footer{
color:#CCC;
height: 48px;

position:fixed;
z-index:5;
bottom:0px;
width:100%;
padding-left:2px;
padding-right:2px;
padding:0;

border-top:1px solid #444;

background:#222; /* Old browsers */
background:-webkit-gradient(linear, 0 0, 0 100%, color-stop(0, #999), color-stop(0.02, #666), color-stop(1, #222));  
background:    -moz-linear-gradient(top, #999, #666 2%, #222); /* FF3.6+ */    
background: -webkit-linear-gradient(top, #999, #666 2%, #222); /* Chrome10+,Safari5.1+ */
background:      -o-linear-gradient(top, #999, #666 2%, #222); /* Opera 11.10+ */
background:     -ms-linear-gradient(top, #999, #666 2%, #222); /* IE10+ */
background:         linear-gradient(top, #999, #666 2%, #222); /* W3C */
}

And when I press on the textbox, the footer elementer jumps up above the virtual keyboard. It used to work when my iDevices was running on versions before ios 7.

On the left side is before pressing the textbox and on the right side is after pressing the textbox.

Left side: Before. Right side: After

The footer jumps above the virtual keyboard.

UPDATE:

I've changed the meta tag provided by Opossum and now the footer stays at the bottom:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!--<meta name="viewport" content="initial-scale=1.0, user-scalable=0">-->
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, target-densityDpi=device-dpi"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />

Extension

This is not a part of the question, but the fix screws things up when running on a Android :) Any solution for that?

Solution: removed maximum-scale and target-densityDpi and now it works for both IOS and Android. The meta tag now looks like this:

<meta name="viewport" content="initial-scale=1.0, user-scalable=0, width=device-width, height=device-height"/>
Phu Minh Pham
  • 1,025
  • 7
  • 21
  • 38
  • 1
    There are two issues with setting the meta-tag to height=device-height. 1) The status bar needs 20px. If you provide 20px from the webview in the app, you'll have a web page that spans 20px below the screen. Meaning: you always get a scroll, no matter how little info there is on your page. 2) When the keyboard is up, you can reach the fixed element by scrolling the 548px (iPhone 5 and newer) to the bottom. This was not the way it used to be. – hnilsen Jan 15 '14 at 19:38

7 Answers7

40

EDIT: Okay, I found another possible solution. Check your html meta tags for something like this:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0">

Replace it with this:

<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, target-densityDpi=device-dpi" />

This fixed the problem for me. I should note that my app is using Cordova though.

Another possible solution:

If you look in config.xml (probably under the resources directory, you should see a line that says:

<preference name="KeyboardShrinksView" value="false" />

If you set that to true, it keeps footers from moving above the soft keyboard. However, this also causes the keyboard to sometimes cover up the text field that the user is typing in.

hshepherd
  • 995
  • 9
  • 14
  • Maybe I'm swining and missing here, but this fix is for an iOS app. As I read it, the poster has his app on a webpage? – Index Sep 24 '13 at 20:10
  • No sorry, this is a webpage which acts as an app when you save the link to your home screen. it works fine when you type in the address in safari, but when you save the link to your home screen = the problem – Phu Minh Pham Sep 25 '13 at 06:00
  • seems like i don't have the config.xml. is it because its developed in asp.net? – Phu Minh Pham Sep 25 '13 at 06:03
  • I see. If that isn't an option, I guess it falls back to the CSS. I am currently trying to find a workaround in the CSS and I'll let you know if I find anything. – hshepherd Sep 25 '13 at 13:24
  • I seem to have fixed this issue in my app. Check my solution edit and see if that works for you. – hshepherd Sep 25 '13 at 13:55
  • It works! Thank you! Changed the meta tag with your replacement and now the footer stays down! You can see the meta tags in my update – Phu Minh Pham Sep 26 '13 at 06:58
  • Awesome! Glad I could help. It was really annoying me too. – hshepherd Sep 26 '13 at 18:55
  • Do you get the problem that the footer is peeking up above the virtual keyboard when (without scrolling) you press on a input box, hide the keyboard, press another input box just below the first one, hide the keyboard again and press another input box below the second input box? – Phu Minh Pham Sep 27 '13 at 08:38
  • This happens when I run it from home screen and in safari. Can this be related to scaling? Safari in iOS 7 shrinks the address bar and hides the nav bar. – Phu Minh Pham Sep 27 '13 at 08:43
  • Hmm, I can't seem to replicate this. Is the footer actually on top of the keyboard or is it just peeking above it? – hshepherd Sep 27 '13 at 13:24
  • When you go from the top input box and approaching downwards, eventually you'll see the keyboard peeking above it and when you continue, you'll ending up having the footer above the keyboard. Sorry for the late post, but i didn't get a notif. about it – Phu Minh Pham Oct 01 '13 at 06:20
  • 4
    Be careful adding height=device-height to the meta tag - it messes with all sorts of css and javascript height / positioning rules. Having said that, it seems to be the only solution for fixing the onscreen keyboard issues. I'm trying to work out a way where I can add the "height=device-height" setting programatically, i.e. only when the iOS keyboard appears. – asgeo1 Oct 04 '13 at 23:26
  • 1
    So @Opossum the height=device-height does keep the footer from "jumping" up to the top of the virtual keyboard BUT it introduces a new problem (for me at least) - if you close the keyboard by pressing "done" everything works BUT if you close the keyboard by blurring the input element (i.e. by clicking somewhere else on the screen outside the input), the footer THEN jumps up and gets stuck where the top of the virtual keyboard used to be - and the only way to get it to go back to the bottom is to scroll the page.. Can anyone else reproduce this and/or have a fix? – Luke Madera Oct 18 '13 at 00:14
  • 1
    So I think I fixed my issue, it requires: $('body').css('height', '+=9999').css('height', '-=9999'); on blur of the input - that seems to trigger a scroll bar and then the fixed elements go back to where they should be. Note I've seen a similar fix with just '1' instead of '9999' but that didn't work for me - in this case I think it needs to be enough to force a scroll bar to be visible. – Luke Madera Oct 19 '13 at 23:59
  • 1
    I had the same issue with the bar getting stuck when pressing somewhere outside the input boxes, when pressing the done button all worked as expected. I used window.scrollBy(0, 0); to update the view. Also I had to use a 350ms timeout for the keyboard to disappear. – MrTimpi Oct 22 '13 at 06:29
  • This solved my fixed footer issue. Thanks a million. :) – Sanjay D Mar 27 '14 at 17:04
6

There's the culprit in your #footer class bottom:0px; If you give bottom to any element, on appearance of virtual keyboard, those elements move upwards in iOS 7. The workaround is to use top property.

T J
  • 42,762
  • 13
  • 83
  • 138
Tanveer Shaikh
  • 1,678
  • 14
  • 27
  • 3
    just an add, it happens in my android jelly bean as well. but i cannot see how top property solve my layout since the element meant to be stuck on the bottom? please advice – bondythegreat Apr 25 '14 at 11:04
3

Approved answer works, but can mess with some CSS, so I have to use something else. It's not my fix, but found it on the internet and it worked for me:

HTML:

<body onResize="onResize();">

JavaScript:

function onResize(){
    var ios7 = (device.platform == 'iOS' && parseInt(device.version) >= 7);
    if (ios7){
        var height = $('body').height();
        if (height < 350){ // adjust this height value conforms to your layout
            $('.myBottomMenu').hide();
        }
        else {
            $('.myBottomMenu').show();
        }
    }
}
Jaroslav
  • 1,389
  • 14
  • 27
  • For a specific iOS fix you really shouldn't be using inline javascript especially when its a resize event. Checking for iOS before running resize event will greatly improve performance `$(document).ready(function () { var ios7 = (device.platform == 'iOS' && parseInt(device.version) >= 7); if (ios7){ $(window).on("resize",function(){ //your iOS fix here }); } });` – Mac Dec 19 '14 at 19:18
3

I'm a bit late but this works well:

var footer = $(".footer");
footer.css({ "top": footer.position().top, "bottom": "auto"});

This assumes a fixed or absolutely positioned element that has bottom: some number originally. Add this to wherever it is appropriate in your javascript scripts (probably on a function that is called when the page loads). This uses jQuery but it easily translates into javascript. This basically forces the footer to stay on the bottom related by the 'top' value instead of the ;bottom' value.

user3718546
  • 323
  • 4
  • 12
  • 1
    That's a good solution to my needs. But there's one problem. If the page is scrollable, footer does not appear in proper position. Especially in case where page is auto scrolled when tapper on a field – Umair Nov 27 '14 at 08:29
1

Here is how we have resolved it: cordova 2.9.0. Solution 1. adding the viewport meta tag did resolve to some extent but not completely.Hence dropped it. Solution 2.

$(document).on('focus','input, select, textarea',function() {
        if(OSName=== 'iOS' && ver[0] === 7){
                if($(this).attr('readonly')===undefined){
                        $('#footer').hide()
                }
         }
});
$(document).on('blur','input, select, textarea',function(){
             if(OSName=== 'iOS' && ver[0] === 7){
                   if($(this).attr('readonly')===undefined){
                   $('#footer').show();
                   }
              }
});

where #footer is the id of the div whihc holds footer. This will show the toolbar for a flash of a second and the hide it, to avoid this flicker we have added some code in the native, 1.Register for the keyboardshow event in your MainViewcontroller.m add the following in the init functioon:

//fix for ios7 footer is scrolled up when the keyboard popsup.
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(keyboardWillShow:)
                                                     name:UIKeyboardWillShowNotification
                                                   object:nil];

2.add the following function

-(void)keyboardWillShow:(NSNotification*)notification{
    //call the javascript to hide the footer.
    //fix for ios7 footer is scrolled along wiht the content when the keyboard comesup.
    if (IsAtLeastiOSVersion(@"7.0")){
        [self.webView stringByEvaluatingJavaScriptFromString:@"()"];
    }
}

3.In the js file add the function

//Fix for footer is misalligned when the virtual keyboard pops up ios7
//check for device is iPhone and os version is 7
function hideFooter(){
    if(OSName=== 'iOS' && ver[0] === 7){
        if($(this).attr('readonly')===undefined)
            $('#footer').hide();
    }
}

Let us know if this solution works for u.

Community
  • 1
  • 1
0

In my case I used to capture the event when entering into input text fields events and hiding the bottom bar using

if($(event.target).hasClass("inputtextfield")){

        $('.bottom_bar').hide();}

and capture the event when the keyboard is closed and show back the keyboard using

document.addEventListener('focusout', function(e) { $('.bottom_bar').show();});
kavinhuh
  • 739
  • 1
  • 9
  • 30
-3

Main issue in you CSS class property

footer{}

You have set the position "fixed" and z-index.

Please handler position property according to to Iphone.

Community
  • 1
  • 1