13

I find that if I use WKWebView with

viewport-fit=cover

and

body :{height:100%}

the height of html body still can not reach the bottom of iPhone X and is equal to the height of safeArea, However, the background-color can cover the fullscreen.

https://ue.qzone.qq.com/touch/proj-qzone-app/test.html

I load this page in a fullscreen WKWebView to reproduce the problem.

WATER1350
  • 141
  • 1
  • 1
  • 6
  • What's worse, the value of window.innerHeight is incorrect which does not happen on UIWebView. – WATER1350 Nov 07 '17 at 02:00
  • 1
    This does not effect only the iPhone X, but also any other iOS 11 device, since they have `safe-area-inset-top` correspond to the status bar height. Thus you get a 20px gap at the bottom on any iOS 11 device. This was not an issue in iOS 10. – Sampo Mar 21 '18 at 08:34
  • 2
    Additionally, if you turn to landscape and back it fixes the issue. It seems the browser has not yet applied `viewport-fit=cover` before computing the html/body heights or something. – Sampo Mar 21 '18 at 08:38

5 Answers5

23

I was able to fix the issue with (ObjC / Swift):

if (@available(iOS 11.0, *)) {
  webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}

or

if #available(iOS 11.0, *) {
    webView.scrollView.contentInsetAdjustmentBehavior = .never;
}

This setting seems to have the same effect as viewport-fit=cover, thus if you know your content is using the property, you can fix the bug this way.

The env(safe-area-inset-top) CSS declarations still work as expected. WKWebView automatically detects when its viewport intersects with blocked areas and sets the values accordingly.

Documentation for contentInsetAdjustmentBehavior and its parameter values and kudos to @dpogue for the answer where I found the solution.

Sampo
  • 4,308
  • 6
  • 35
  • 51
  • 1
    This ist the only working solution of them all. I am using cordova and set this in CDVWKWebViewEngine.m in line 136 with self.engineWebView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; – plocks Apr 16 '18 at 12:10
  • Works like a charm. Thanks you saved my day buddy – Ankush Apr 23 '18 at 12:06
  • Cordova-ios team is so stubborn, it just doesn't give us any options(such as ``) to control it after so many years – Doctor.Who. Jul 20 '20 at 01:02
  • Thank you Sampo! After fiddling with so many things like splash screens, plugins, css, meta tags, this is the only thing that actually worked. Saved me having to migrate an ionic3 project to 5. For me, had to add code in CDVWebViewEngine.m line 220: – Klaus Rubba Oct 10 '21 at 00:16
12

I found setting height in CSS on the html element to be height: 100vh (rather than height: 100%) worked

Adam Heath
  • 4,703
  • 2
  • 35
  • 50
  • 1
    Wow, this fixed my issue! I had body position set to fixed and overflow hidden (100vh and 100vw) to prevent the rubber band effect, adding 100vh to the html element as well solved it. Thank you – Nichlas Wærnes Andersen Nov 20 '19 at 23:48
1

In your code, if you add

opacity: 0.5;

to the html and body tags you'll see that the body tag does take the full screen while the html tag height is only as tall as the safe area.

If you just want the html area to reach the edges you can explicitly set:

<html style='height: 812px;'>

This will make the content within the html properly fit the full screen as long as you also add:

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

Not the most elegant solution of course, but it does work.

Samantha John
  • 978
  • 1
  • 8
  • 18
  • No, I have added the viewport-fit, but the value of window.innerHeight is still not correct when I load the page in a fullscreen WKWebView, you can try to load the page https://ue.qzone.qq.com/touch/proj-qzone-app/test.html. – WATER1350 Nov 07 '17 at 01:57
  • Edited my answer with a fix. It's a little hacky, but if you just need a fullscreen it'll work. – Samantha John Nov 10 '17 at 01:25
0

I cam across this issue in my Cordova app.

Samantha's solution worked for me to an extent but having a height of 812px set in the html tag was causing issues whilst in landscape and with other devices. Eventually I found that targeting just the iPhone X sized screen with css media queries for both landscape and portrait did the trick.

The width and height pixel values needed to be declared as important in order for the iPhone to accept them.

@media only screen 
    and (device-width : 375px) 
    and (device-height : 812px) 
    and (-webkit-device-pixel-ratio : 3) 
    and (orientation : portrait) { 
        html {
            height: 812px !important;
            width: 375px !important;  
        }
    }

@media only screen 
    and (device-width : 375px) 
    and (device-height : 812px) 
    and (-webkit-device-pixel-ratio : 3) 
    and (orientation : landscape) { 
        html {
            width: 812px !important;
            height: 375px !important;
        }     
    }
0

You need to set UIEdgeInsets for your web view to stretch all the way to bottom (covering the notch).

You can achieve this by creating a subclass of WKWebView!

Check this out.

Rahul Joshi
  • 71
  • 1
  • 6