Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
PhoneGap / Apache Cordova - top margin for iOS 7
// Pre-requisites:
// 1. Device core plugin
// 2. Splashscreen core plugin (3.1.0)
// 3. config.xml: <preference name="AutoHideSplashScreen" value="false" />
// 4. config.xml: <preference name="DisallowOverscroll" value="true" />
function onDeviceReady() {
if (parseFloat(window.device.version) >= 7.0) {
document.body.style.marginTop = "20px";
// OR do whatever layout you need here, to expand a navigation bar etc
}
navigator.splashscreen.hide();
}
document.addEventListener('deviceready', onDeviceReady, false);
@whatificould

This comment has been minimized.

Show comment Hide comment
@whatificould

whatificould Sep 18, 2013

Is this functioning for you? I'm not able to get this to work on my end.

Is this functioning for you? I'm not able to get this to work on my end.

@nettz

This comment has been minimized.

Show comment Hide comment
@nettz

nettz Sep 18, 2013

since phonegap 3.0.0+ you ll need the "Basic device information" plugin

nettz commented Sep 18, 2013

since phonegap 3.0.0+ you ll need the "Basic device information" plugin

@peacemoon

This comment has been minimized.

Show comment Hide comment
@peacemoon

peacemoon Sep 18, 2013

we haven't had phonegap 3.1.0 yet

we haven't had phonegap 3.1.0 yet

@shazron

This comment has been minimized.

Show comment Hide comment
@shazron

shazron Sep 18, 2013

Yeah this needs PhoneGap/Cordova 3.0.0 or greater. The only 3.1.0 thing is the splashscreen plugin, so it doesn't jump around due to the status bar in 7.0

Owner

shazron commented Sep 18, 2013

Yeah this needs PhoneGap/Cordova 3.0.0 or greater. The only 3.1.0 thing is the splashscreen plugin, so it doesn't jump around due to the status bar in 7.0

@shazron

This comment has been minimized.

Show comment Hide comment
@shazron

shazron Sep 18, 2013

Technically it should work in 2.9.0, I don't see why not (save the splashscreen plugin, which you may have to patch)

Owner

shazron commented Sep 18, 2013

Technically it should work in 2.9.0, I don't see why not (save the splashscreen plugin, which you may have to patch)

@brainbrian

This comment has been minimized.

Show comment Hide comment
@brainbrian

brainbrian Sep 19, 2013

Here's the command for adding the "Basic device information" plugin
$ phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git

Here's the command for adding the "Basic device information" plugin
$ phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git

@shazron

This comment has been minimized.

Show comment Hide comment
@shazron

shazron Sep 19, 2013

Updated the gist (thanks to the commenters on http://coenraets.org/blog/2013/09/phonegap-and-cordova-with-ios-7/) to detect >= 7.0.

Owner

shazron commented Sep 19, 2013

Updated the gist (thanks to the commenters on http://coenraets.org/blog/2013/09/phonegap-and-cordova-with-ios-7/) to detect >= 7.0.

@shazron

This comment has been minimized.

Show comment Hide comment
@shazron

shazron Sep 19, 2013

Something to consider - on rotation, the status bar height changes.

Owner

shazron commented Sep 19, 2013

Something to consider - on rotation, the status bar height changes.

@leapingbytes

This comment has been minimized.

Show comment Hide comment
@leapingbytes

leapingbytes Sep 22, 2013

looks like there is class x-ios-7 which gets set on body by cordova. can key of this class to make all needed adjustments via CSS.

looks like there is class x-ios-7 which gets set on body by cordova. can key of this class to make all needed adjustments via CSS.

@blefebvre

This comment has been minimized.

Show comment Hide comment
@blefebvre

blefebvre Sep 23, 2013

@leapingbytes I don't think cordova is setting that class. Any chance you're using sencha touch?

@leapingbytes I don't think cordova is setting that class. Any chance you're using sencha touch?

@mullican

This comment has been minimized.

Show comment Hide comment
@mullican

mullican Sep 26, 2013

Using a margin on the body doesn't alter the placement of absolutely-positioned elements within the document. I prefer to use translate3d, as that shifts the entire document while preserving the layout of all its children. Also, calling this on deviceready() can make the shift visible to the user. Doing the following directly in the document head should apply the transform before any rendering happens:

if(navigator.userAgent.match(/iPhone OS 7/)) {
  document.write('<style type="text/css">body{-webkit-transform: translate3d(0,20px,0)}</style>');
}

Using a margin on the body doesn't alter the placement of absolutely-positioned elements within the document. I prefer to use translate3d, as that shifts the entire document while preserving the layout of all its children. Also, calling this on deviceready() can make the shift visible to the user. Doing the following directly in the document head should apply the transform before any rendering happens:

if(navigator.userAgent.match(/iPhone OS 7/)) {
  document.write('<style type="text/css">body{-webkit-transform: translate3d(0,20px,0)}</style>');
}
@JasperCCS

This comment has been minimized.

Show comment Hide comment
@JasperCCS

JasperCCS Sep 26, 2013

Hi.
using version GP 2.3
document.body.style.marginTop = "20px"; works.

But the webview shifts up to 0 after invoking camera , therefore part of the screen is obscured by the status bar again.
any suggestion?

thanks

Hi.
using version GP 2.3
document.body.style.marginTop = "20px"; works.

But the webview shifts up to 0 after invoking camera , therefore part of the screen is obscured by the status bar again.
any suggestion?

thanks

@shazron

This comment has been minimized.

Show comment Hide comment
@shazron

shazron Sep 30, 2013

thanks @mullican - even better

Owner

shazron commented Sep 30, 2013

thanks @mullican - even better

@shazron

This comment has been minimized.

Show comment Hide comment
@shazron

shazron Sep 30, 2013

@JasperCCS - unfortunately a lot of the core plugins need to take this into account, and hide the statusbar, and unhide it (if it was not hidden before) after.

Owner

shazron commented Sep 30, 2013

@JasperCCS - unfortunately a lot of the core plugins need to take this into account, and hide the statusbar, and unhide it (if it was not hidden before) after.

@johnnylambada

This comment has been minimized.

Show comment Hide comment
@johnnylambada

johnnylambada Oct 1, 2013

@mullican - I modified the RE as follows so both iPhone and iPad will work...

      if(navigator.userAgent.match(/iP[ha][od].*OS 7/)) {
        document.write('<style type="text/css">body{-webkit-transform: translate3d(0,20px,0)}</style>');
      }

But this concept isn't working for me because now my header and footer get stuck on the page and scroll with it. #BTTDB

@mullican - I modified the RE as follows so both iPhone and iPad will work...

      if(navigator.userAgent.match(/iP[ha][od].*OS 7/)) {
        document.write('<style type="text/css">body{-webkit-transform: translate3d(0,20px,0)}</style>');
      }

But this concept isn't working for me because now my header and footer get stuck on the page and scroll with it. #BTTDB

@RynoRn

This comment has been minimized.

Show comment Hide comment
@RynoRn

RynoRn Oct 2, 2013

Thanks for the ideas guys! Here is the solution I used and it's working on any kind of iOS 7 device:

var iOS7 = window.device 
                && window.device.platform 
                && window.device.platform.toLowerCase() == "ios"
                && parseFloat(window.device.version) >= 7.0;

if (iOS7) {
    // do the trick here
    // ### I used padding-top: 20px on the body element ###
}

RynoRn commented Oct 2, 2013

Thanks for the ideas guys! Here is the solution I used and it's working on any kind of iOS 7 device:

var iOS7 = window.device 
                && window.device.platform 
                && window.device.platform.toLowerCase() == "ios"
                && parseFloat(window.device.version) >= 7.0;

if (iOS7) {
    // do the trick here
    // ### I used padding-top: 20px on the body element ###
}
@pjayanetti

This comment has been minimized.

Show comment Hide comment
@pjayanetti

pjayanetti Oct 4, 2013

@mullican - Thank you. Your method worked well with jQuery Mobile based UI.

@mullican - Thank you. Your method worked well with jQuery Mobile based UI.

@darly

This comment has been minimized.

Show comment Hide comment
@darly

darly Oct 4, 2013

@johnnylambada Thanks for that, I havent upgraded to 3.x and your solutions works like a charm for 2.x

darly commented Oct 4, 2013

@johnnylambada Thanks for that, I havent upgraded to 3.x and your solutions works like a charm for 2.x

@the-machinist

This comment has been minimized.

Show comment Hide comment
@VishalRJoshi

This comment has been minimized.

Show comment Hide comment
@VishalRJoshi

VishalRJoshi Nov 11, 2013

If you never created the phonegap project using phonegap CLI then it is a real pain to install the plugins (Step 1 & 2) using it. Try using plugman instead. The command which worked for me to install the device core plugin was

plugman install --platform ios --project "/Users/Vishal/Documents/Dev/Celebrations/app/ios" --plugin https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git

The project directory is the location of your xcode project which contains phonegap config.xml

If you never created the phonegap project using phonegap CLI then it is a real pain to install the plugins (Step 1 & 2) using it. Try using plugman instead. The command which worked for me to install the device core plugin was

plugman install --platform ios --project "/Users/Vishal/Documents/Dev/Celebrations/app/ios" --plugin https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git

The project directory is the location of your xcode project which contains phonegap config.xml

@VishalRJoshi

This comment has been minimized.

Show comment Hide comment
@VishalRJoshi

VishalRJoshi Nov 11, 2013

And to install the splashscreen plugin try

plugman install --platform ios --project "/Users/VishalRJoshi/Documents/Dev/Celebrations/app/ios" --plugin https://git-wip-us.apache.org/repos/asf/cordova-plugin-splashscreen.git

And to install the splashscreen plugin try

plugman install --platform ios --project "/Users/VishalRJoshi/Documents/Dev/Celebrations/app/ios" --plugin https://git-wip-us.apache.org/repos/asf/cordova-plugin-splashscreen.git

@VishalRJoshi

This comment has been minimized.

Show comment Hide comment
@VishalRJoshi

VishalRJoshi Nov 11, 2013

And since I was using Angular.js for my app the code which worked for me inside deviceready listener of cordova was as below:

if(navigator.userAgent.match(/iPhone OS 7/)) {
document.body.style.marginTop = "20px";
}

Hope this helps!!

And since I was using Angular.js for my app the code which worked for me inside deviceready listener of cordova was as below:

if(navigator.userAgent.match(/iPhone OS 7/)) {
document.body.style.marginTop = "20px";
}

Hope this helps!!

@AndrewJHart

This comment has been minimized.

Show comment Hide comment
@AndrewJHart

AndrewJHart Jan 15, 2014

thanks, simple & easy.

thanks, simple & easy.

@ghost

This comment has been minimized.

Show comment Hide comment
@ghost

ghost Jan 29, 2014

I would say just add a class on your body tag with JS if it is iOS7.

This will allow you to select with the iOS class in your CSS files and apply styles that are specific to iOS7. This way your styles are not buried in some JS file.

Makes it easier to find.

ghost commented Jan 29, 2014

I would say just add a class on your body tag with JS if it is iOS7.

This will allow you to select with the iOS class in your CSS files and apply styles that are specific to iOS7. This way your styles are not buried in some JS file.

Makes it easier to find.

@garnold

This comment has been minimized.

Show comment Hide comment
@garnold

garnold Mar 25, 2014

Tying it all together, taking a stab at @jlongnbt 's suggestion, using Cordova merges:

  • Install the "Device" plugin:
cordova plugin add org.apache.cordova.device
  • Create a file merges/ios/css/platform.css with the contents:
body.iOS7 {
    -webkit-transform: translate3d(0, 20px, 0);
}
  • Create a file merges/ios/js/platform.js with the contents:
$(document).on('deviceready', function () {
    if (window.device && parseFloat(window.device.version) >= 7.0) {
        $('body').addClass('iOS7');
    }
});
  • Add references to platform.css and platform.js to www/index.html:
    <head>
        <!-- ... -->
        <link rel="stylesheet" type="text/css" href="css/index.css" />
        <link rel="stylesheet" type="text/css" href="css/platform.css"/>
        <!-- ... -->
    </head>
    <body>
        <!-- ... -->
        <script type="text/javascript" src="js/index.js"></script>
        <script type="text/javascript" src="js/platform.js"></script>
        <!-- ... -->
    </body>
  • Ship it!

garnold commented Mar 25, 2014

Tying it all together, taking a stab at @jlongnbt 's suggestion, using Cordova merges:

  • Install the "Device" plugin:
cordova plugin add org.apache.cordova.device
  • Create a file merges/ios/css/platform.css with the contents:
body.iOS7 {
    -webkit-transform: translate3d(0, 20px, 0);
}
  • Create a file merges/ios/js/platform.js with the contents:
$(document).on('deviceready', function () {
    if (window.device && parseFloat(window.device.version) >= 7.0) {
        $('body').addClass('iOS7');
    }
});
  • Add references to platform.css and platform.js to www/index.html:
    <head>
        <!-- ... -->
        <link rel="stylesheet" type="text/css" href="css/index.css" />
        <link rel="stylesheet" type="text/css" href="css/platform.css"/>
        <!-- ... -->
    </head>
    <body>
        <!-- ... -->
        <script type="text/javascript" src="js/index.js"></script>
        <script type="text/javascript" src="js/platform.js"></script>
        <!-- ... -->
    </body>
  • Ship it!
@louisdoe

This comment has been minimized.

Show comment Hide comment
@louisdoe

louisdoe May 13, 2014

Hi, it is possible to call the "core device plugin" in a Phonegap Build app ? Like this maybe :
gap:plugin name="org.apache.cordova.Device"
?

Thanks

Hi, it is possible to call the "core device plugin" in a Phonegap Build app ? Like this maybe :
gap:plugin name="org.apache.cordova.Device"
?

Thanks

@diaswrd

This comment has been minimized.

Show comment Hide comment
@diaswrd

diaswrd Jul 25, 2014

@louisdoe Yes, I'm using phonegap build to create my .apk and .ipa files with <gap:plugin name="org.apache.cordova.device" /> in my config.xml file. Without problems.

diaswrd commented Jul 25, 2014

@louisdoe Yes, I'm using phonegap build to create my .apk and .ipa files with <gap:plugin name="org.apache.cordova.device" /> in my config.xml file. Without problems.

@luckywildcat

This comment has been minimized.

Show comment Hide comment
@luckywildcat

luckywildcat Aug 7, 2014

I am injecting the style by adding this to the script in the head:
if(navigator.userAgent.match(/iP[ha][od].*OS 7/)) {
document.write('<style type="text/css">body{-webkit-transform: translate3d(0,20px,0)}</style>');
}
Problem is, the status bar then has a white background on ios7+, pre iOS7 it shows black background statusbar with light content. I want it to have a blue background on any iOS version.

I tried changing the XIB to blue background, but that won't work since it seams to move the entire view down 20px.

Thoughts? TIA

(It's using UIStatusBarStyleDefault)

I am injecting the style by adding this to the script in the head:
if(navigator.userAgent.match(/iP[ha][od].*OS 7/)) {
document.write('<style type="text/css">body{-webkit-transform: translate3d(0,20px,0)}</style>');
}
Problem is, the status bar then has a white background on ios7+, pre iOS7 it shows black background statusbar with light content. I want it to have a blue background on any iOS version.

I tried changing the XIB to blue background, but that won't work since it seams to move the entire view down 20px.

Thoughts? TIA

(It's using UIStatusBarStyleDefault)

@dmcg

This comment has been minimized.

Show comment Hide comment
@dmcg

dmcg Aug 13, 2014

Good discussion here
http://blogs.telerik.com/appbuilder/posts/13-11-07/everything-hybrid-web-apps-need-to-know-about-the-status-bar-in-ios7
but I couldn't get the referenced plugin to work

The webkit-transform knackers JQuery Mobile for me, as its footers are now off the bottom of the page. The best overall I've found for JQM is

    document.body.style.marginTop = "20px";
    $(".ui-header").css("margin-top", "20px");

dmcg commented Aug 13, 2014

Good discussion here
http://blogs.telerik.com/appbuilder/posts/13-11-07/everything-hybrid-web-apps-need-to-know-about-the-status-bar-in-ios7
but I couldn't get the referenced plugin to work

The webkit-transform knackers JQuery Mobile for me, as its footers are now off the bottom of the page. The best overall I've found for JQM is

    document.body.style.marginTop = "20px";
    $(".ui-header").css("margin-top", "20px");
@johnhight

This comment has been minimized.

Show comment Hide comment
@johnhight

johnhight Aug 31, 2014

@dmcg Yes, using JQuery Mobile too, and the webkit-transform whites out the whole page, but your solution works great for me.

@dmcg Yes, using JQuery Mobile too, and the webkit-transform whites out the whole page, but your solution works great for me.

@identy

This comment has been minimized.

Show comment Hide comment
@identy

identy Sep 30, 2015

body . padding -20px

by identy

identy commented Sep 30, 2015

body . padding -20px

by identy

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