16

In my case I'm running a web app on iPhone X, I'm trying to add a padding on top to push my body to the safe area using the safe area css attributes of Webkit padding-top: constant(safe-area-inset-top); and padding-top: env(safe-area-inset-top);. However the web view doesn't evaluate correctly these attributes and it's always set to 0. What should I dod to make it work ! code :

body {
padding-top: 44px;
    padding-top: constant(safe-area-inset-top);
    padding-top: env(safe-area-inset-top);
}

enter image description here

enter image description here

Oussama Haff.
  • 524
  • 1
  • 3
  • 14

5 Answers5

27

it needs

<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"> 

in the head section of your HTML

Albi Patozi
  • 1,182
  • 13
  • 19
  • 4
    In my case, my meta tag which I grabbed from developer.mozilla (top hit on google) was missing the viewport-fit=cover which seems to be the important bit. – elmarko Jul 05 '20 at 16:35
  • In my case change the order of value of content in meta tag fix the issue. place viewport-fit=cover as first value of content. – reza jafari May 03 '22 at 05:55
  • This is not working for me in iOS 14.5 or 16.4 simulators. Still `0px` – pejalo Aug 18 '23 at 20:11
4

Firstly, safe-area-inset-dir is undefined on Chrome and Safari on mac, where I suspect you're measuring the padding. To my knowledge, you'll have to load the site on an iOS 11 device in Safari to see this variable have any value. I suspect this is why you have the 0px padding issue.

Also, as of iOS 11.2, the keyword to use is env. In fact, the iPhone X design guidelines references this and even includes a nice full example for detecting support for it:

@supports(padding: max(0px)) {
    .post {
        padding-left: max(12px, env(safe-area-inset-left));
        padding-right: max(12px, env(safe-area-inset-right));
    }
}

This pattern will do a few things for you:

  • Since max is not part of standard CSS, we know that we're on Safari / Webkit, where safe-area-inset-dir should be defined (where dir is a direction).
  • Also this will set the padding of the element to either your desired 'normal' padding (12px in this case) on most devices or the needed safe area space if you're on an iPhone X. This is because iOS 11 on the iPhone 8 will define this variable as 0, which would result in padding of 0px otherwise.
Hawkins
  • 700
  • 6
  • 21
  • 2
    It seems `min()` and `max()` will become standard CSS functions soon. So in near future this rule might target even other devices/browser than iPhone X. See https://drafts.csswg.org/css-values/#calc-notation. – Kout Jun 13 '18 at 13:18
  • 1
    Good job looking out, thanks for that info! Apple will probably revise the blog post I linked in the future (as should we this answer) to detect `env` instead of `max` in `@supports`, if I had to guess. When this day comes, I'm not sure how this code will behave when the `@supports` resolves true but `env` is undefined in browsers like Chrome, Firefox. We may be able to have `padding-left: 12px;` and `padding-left: max(12px, env(safe-area-inset-left));` on the following line and just have Chrome mark the rule invalid and default to `12px` as a side effect. – Hawkins Jun 13 '18 at 14:20
  • Great! Adding that fallback line would be safer. Although it is still not the time, it would be future proof => I will rather add it in my code now :) – Kout Jun 14 '18 at 09:08
  • Does this whole code snippit go inside of the body {} rule set? I'm not familiar with the use of @ in a css file. – Alex Apr 28 '21 at 15:55
3

This will work like a charm for ionic v3 (or less):

Add this to your index.html

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

then in yout global.scss

.ion-app {
  --safe-area-inset-top: env(safe-area-inset-top);
  --safe-area-inset-bottom: env(safe-area-inset-bottom);
  height: calc(100% + (var(--safe-area-inset-top) + var(--safe-area-inset-bottom)));
}

in ionic v4 and later seems that this issue is already fix.

Cristian Zumelzu
  • 842
  • 10
  • 15
0

without the line padding-top: env(safe-area-inset-top); it should work

Sabine
  • 77
  • 1
  • 1
  • 5
0
/* safe area in ios and android handled */
body {
  --ion-safe-area-top: env(safe-area-inset-top);
  --ion-safe-area-bottom: env(safe-area-inset-bottom);
}

this works for me

Pencilcheck
  • 2,664
  • 3
  • 25
  • 14