CSS safe area attributes doesn't work on iPhone X

20,609

Solution 1

it needs

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

in the head section of your HTML

Solution 2

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.
Share:
20,609
Oussama Haff.
Author by

Oussama Haff.

Mobile Software Engineer working mainly on native Android

Updated on July 10, 2022

Comments

  • Oussama Haff.
    Oussama Haff. almost 2 years

    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

  • Kout
    Kout almost 6 years
    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 drafts.csswg.org/css-values/#calc-notation.
  • Hawkins
    Hawkins almost 6 years
    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.
  • Kout
    Kout almost 6 years
    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 :)
  • elmarko
    elmarko almost 4 years
    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.
  • Alex
    Alex about 3 years
    Does this whole code snippit go inside of the body {} rule set? I'm not familiar with the use of @ in a css file.
  • reza jafari
    reza jafari almost 2 years
    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. <meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0">