41

I have a native iOS app with a webview to display web content. I have a fixed header in my app with the following properties:

#header {
    height: 60px;
    background-color: @mainColor;
    color: #ffffff;
    padding: 10px;
    text-align: center;
    position: fixed;
    width: 100%;
    z-index: 1;
}

Before I upgraded to iOS 11 everything worked fine. Now when I scroll down/up the header disappears during the scroll, and when the scroll is done, the header appears again.

This can also be reproduced in Xcode 8.

Paolo Forgia
  • 5,804
  • 7
  • 39
  • 55
Bergerova
  • 773
  • 3
  • 8
  • 20
  • 1
    Maybe defining `top: 0px; left: 0px;` helps? – Manuel Otto Oct 04 '17 at 14:47
  • @abarax: I am afraid of that have no solution if keep using `position: fixed`. Recommend to use [position: absolute](https://stackoverflow.com/a/46597494/4254681) – Duannx Nov 06 '17 at 04:55
  • @Bergerova check my edited answer what Apple's official doc saying..? we should use `WKWebView` instead of `UIWebView` or `WebView` – iPatel Nov 09 '17 at 05:01
  • @iPatel, it still doesn't solve the issue for me. Using WKWebView solved your issue? – Bergerova Nov 11 '17 at 18:47
  • @Bergerova: as per the apple docs you should use WkWebview only. did you try with that or not? pls let me know – Dhanunjay Kumar Nov 12 '17 at 10:34
  • @Dhanunjay Kumar, yes, I have replaced the old WebView with WKWebView, but the fixed header still disappears – Bergerova Nov 13 '17 at 12:46

11 Answers11

15

I'm just writing some code, try with one by one

From Apple official note:

Important:

Starting in iOS 8.0 and OS X 10.10, use WKWebView to add web content to your app. Do not use UIWebView or WebView.

So you should try once with WKWebView.

Paolo Forgia
  • 5,804
  • 7
  • 39
  • 55
iPatel
  • 41,165
  • 13
  • 109
  • 131
13

position: fixed has always been a problem with iOS. It seems that in every version of iOS the problem persists. Now, I couldn't find anything regarding the change of behaviour of your application from iOS 10 to 11, you could consider reporting this as a bug; on the other hand having seen the multitudes of people who encountered this problem and the fact that affects more or less all the recents versions of iOS I would suggest not to use position: fixed.

The most common workaround is transform: translateZ(0), this not only works on iOS and prevent any possible flickering, it also forces the browser to use hardware acceleration to access the GPU to make pixels fly. It should work also without the prefix -webkit- from iOS 9.

Paolo Forgia
  • 5,804
  • 7
  • 39
  • 55
6

I had this very similar issue with a Cordova project built for iOS, which uses a webview. Cordova uses the UIWebView by default as its webview engine and I tried all the possible fixes mentioned in this thread and many others. Finally our only solution was to change the webview engine from UIWebView to WKWebView (https://developer.apple.com/documentation/webkit/wkwebview). With Cordova, introducing the WKWebView is pretty straightforward with a plugin https://github.com/apache/cordova-plugin-wkwebview-engine

After introducing WKWebView and dealing with some of the issues it causes we are no longer experiencing the flickering or disappearing fixed positioned elements while scrolling in iOS 11.

calle
  • 808
  • 1
  • 5
  • 7
  • This fixed it for me too. But it breaks other stuff, like downloading and accesssing files. How is this not a bigger issue? Cordova pracitcally being unusable for the newes iOS release? – David Schumann Oct 11 '17 at 14:10
  • It didnt work for me, somehow my angular didnt load, just have a blank screen. – Akash Pal Oct 12 '17 at 05:38
  • This answer is actually working for me. I'm not sure if it's appropriate to reward the bounty for it though, as it does not solve the problem with the standard UIWebView. However if we hit the deadline this might be the one that gets it. – abarax Nov 09 '17 at 05:45
6

We had the similar issue and it got fixed with below 2 plugins

https://github.com/apache/cordova-plugin-wkwebview-engine https://github.com/TheMattRay/cordova-plugin-wkwebviewxhrfix

First plugin will change default WebView to WKWebView and second plugin provide fix for CORS issue that we see for using WKWebView.

Dilip
  • 529
  • 1
  • 8
  • 20
  • That's worked perfect for me! Actually event improved the usability of my app with this wkwebview engine... Thanks a lot!!! – Igor Trindade Dec 23 '17 at 18:13
  • This worked perfectly. Still have to test the app fully with WKWebView. Important: Important Note: Starting in iOS 8.0 and OS X 10.10, use WKWebView to add web content to your app. Do not use UIWebView or WebView. – Akash Pal Dec 28 '17 at 20:20
  • Dilip, Im using phonegap build and the engine plugin is on npm so it installs. But how do I install the wkwebviewxhrfix? Do I include the folder src/ios to my project? Thanks. – Claes Gustavsson Apr 23 '18 at 18:06
  • @ClaesGustavsson - Try with "phonegap plugin add https://github.com/TheMattRay/cordova-plugin-wkwebviewxhrfix". If that does not help, you can probably download the whole repo from github on your project folder and then install the same from there. – Dilip Apr 25 '18 at 04:24
  • Thanks Dilip. With the https://github.com/TheMattRay/cordova-plugin-wkwebviewxhrfix can I load file from my server with that or just local files in the phone? – Claes Gustavsson May 02 '18 at 17:05
  • You should be able to install from the server. "phonegap plugin add github.com/TheMattRay/cordova-plugin-wkwebviewxhrfix" not working ? – Dilip May 03 '18 at 17:16
4

The trick is to force GPU acceleration. Do this by adding translate3d to the #header element.

transform: translate3d(0,0,0);

If elements nested inside the #header element continue to disappear add translate3d to them as well.

Dedering
  • 408
  • 2
  • 10
1

Position fixed doesn't work well with iOS, but I used position absolute in my cordova apps which never causes any issue for me.

Tapas
  • 998
  • 6
  • 14
1

You may have already seen this post on some changes in iOS 11, but if not maybe it would apply to your situation?

One of the viewport-fit: contain/cover/auto options?

Or changing your code to use a constant value for the padding-top?

Ben
  • 2,303
  • 1
  • 15
  • 19
0

Did you try to use position:sticky instead of position:fixed?

In past it works really well on iOS. Please make note that is position:sticky requered rule top to be defined.

So final solution in your case should be:

#header {
    height: 60px;
    background-color: @mainColor;
    color: #ffffff;
    padding: 10px;
    text-align: center;
    position: -webkit-sticky;
    position: sticky;
    top: 0;
    width: 100%;
    z-index: 1;
}

Also if you need extra offset from top you could adjust top:0; rule from zero to any number in px.

And one more final note: that is sticky element will not extract element from document flow and will act as ordinary document element (like div with position:static or relative), but not like absolute positioned element (in case of fixed or absolute).

http://caniuse.com/#feat=css-sticky

Andrew Ymaz
  • 1,015
  • 5
  • 10
0

I have been battling against this very same problem myself.

The issue (at least as manifested in the app I am working on) only seems to happen on screens which are a combination of tall (in that they require a good deal of scrolling) and fairly complex.

Generally, at least for me, the problem only seems to really manifest when momentum scrolling kicks in.

Although there's one screen in particular, which contains 15 left-right-scrollable rows of images, that will break the head/footer no matter how slowly you scroll it.

In my own defense... I had absolutely nothing to do with the design. :-)

At any rate...

After much searching an experimentation, I have managed to come up with a "solution" of sorts.

Mind you, I'm not claiming this is the way to go here. But perhaps someone with more experience than I have in the mobile app space, can take this information and extrapolate something less sucky from it.

The first piece looks like this:

html,
body {
    position: fixed;
    width: 100%;
    height: 100%;
    overflow: hidden;
    -webkit-overflow-scrolling: auto;
}

And then for the container that acts as the main body of your screen:

.main-content-area {
    overflow-y: auto;
    height: 100%;
}

This is going to kill momentum scrolling for your app. Which is not great, I know. But as a result of curtailing the user's ability to scroll very quickly, screen rendering seems to be able to keep up and the problem goes away.

Again, I'm not recommending this as a viable solution for production. Because it's obviously not great.

I'm offering this up more as a possible stepping-stone to a real solution, in the hopes that it helps.

===>>> UPDATE:

I have a working solution. But, as others before me have pointed out, I had to avoid the use of Fixed Positioning.

Instead, I used Absolute Positioning to define Header, Footer and Main Content sections of the page. Then allowed scrolling only in the Main Content section.

If it helps, I have the POC I put together available on BitBucket

Oook
  • 21
  • 1
  • 4
  • Hi, thank for your answer. I already tried this solution, but as you said, it cannot be a valid solution in production. The scrolling becomes very slow... – Bergerova Oct 14 '17 at 17:30
  • 1
    Yeah... I wish I had something better to report. This issue is making me nuts. It doesn't help that I'm fairly new to this sort of thing. I'll keep working on it and watching this space. Somebody has to come up with a solution sooner or later. – Oook Oct 16 '17 at 14:38
0

this works for me

position: sticky
0

I had this same issue with both position:fixed and position:sticky. Chaging from UIWebView to WKWebView fixed it for me:

#import <WebKit/WebKit.h>

....

@property (weak, nonatomic) IBOutlet WKWebView *myWebView;

"Starting in iOS 8.0 and OS X 10.10, use WKWebView to add web content to your app. Do not use UIWebView or WebView."

https://developer.apple.com/documentation/webkit/wkwebview

claytronicon
  • 1,122
  • 10
  • 15