WKWebView page height issue on iPhone X
Asked Answered
K

5

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.

Kelcey answered 6/11, 2017 at 10:5 Comment(3)
What's worse, the value of window.innerHeight is incorrect which does not happen on UIWebView.Kelcey
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.Gerbold
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.Gerbold
G
26

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.

Gerbold answered 21/3, 2018 at 11:20 Comment(5)
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;Osmo
Works like a charm. Thanks you saved my day buddyExhibitioner
Cordova-ios team is so stubborn, it just doesn't give us any options(such as <preference>) to control it after so many yearsInchworm
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:Demonography
Dude I'm going to cry... this worked like a charm thank you. What a headache..Fink
F
12

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

Firry answered 13/12, 2018 at 5:17 Comment(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 🙌Schecter
J
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.

Jacinda answered 6/11, 2017 at 18:50 Comment(2)
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 ue.qzone.qq.com/touch/proj-qzone-app/test.html.Kelcey
Edited my answer with a fix. It's a little hacky, but if you just need a fullscreen it'll work.Jacinda
T
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;
        }     
    }
Takakotakakura answered 29/11, 2017 at 20:37 Comment(0)
P
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.

Pyroconductivity answered 23/1, 2020 at 12:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.