Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Chrome calculates the wrong height of the document

In order to fill the whole height of the page, I use height: 100%; for html and body tags, and it works fine until a browser would be closed and reopened. (I don't use 100vh because of issues on mobile devices https://nicolas-hoizey.com/2015/02/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile-browsers.html )

Steps to reproduce:

  • Open https://angelika94.github.io/rick/ in Google Chrome on iPhone (you will see that navigation (Morty and Beer) is placed on the bottom of the page) screenshot of css Rick with navigation
  • close the browser and remove it from multitasking navigation: https://support.apple.com/en-us/HT201330
  • open the browser again (you will see that bottom navigation moved off the "first screen" and now you need to scroll to see it) screenshot of css Rick without navigation

the page will be fixed by itself in these cases:

  • update page
  • rotate the device to landscape
  • open and close browser's navigation by tabs
  • close and reopen browser without closing it in multitasking nav

Why does it happen? How can I fix this behavior?

Thank you in advance!

like image 746
Anzhelika Avatar asked Nov 19 '19 13:11

Anzhelika


1 Answers

I had a very different issue, but I think the solution I worked out may work for your situation also, because you mentioned updating the page would fix it.

So I had issues with chrome on android where if you scroll very quickly (not uncommon on mobile), some elements would fail to get re/painted. Searched everywhere for a solution but couldn't find anything that would work.

Finally, I figured out a working fix:

.pagewrap {
  transform: translateZ(0);
  animation-name: 'repaint';
  animation-duration: 3s;
  animation-iteration-count: infinite;
  animation-play-state: running;
  animation-timing-function: linear;
}

@keyframes repaint {from { zoom: 99.99999%; } to { zoom: 99.99998%; }}

So what this does is forces the page to continually repaint on a 3 second cycle.

Maybe I should tweak it to only shift for a fraction of a second every 2 seconds, instead of continually:

.pagewrap {
  transform: translateZ(0);
  animation-name: 'repaint';
  animation-duration: 2s;
  animation-iteration-count: infinite;
  animation-play-state: running;
  animation-timing-function: linear;
}

@keyframes repaint {
  0% {
    zoom: 99.99999%;
  }
  99% {
    zoom: 99.99999%;
  }
  100% {
    zoom: 99.99998%;
  }
}

I tried zoom: 99.99999; to 1 but certain elements that transitioned scale above 1 on some hover effects would show the zoom breathing. So 99.99999 to 99.99998 was what worked for me to make the effect invisible.

Slightly hacky solution that could present performance issues for very long pages, but maybe not, because the browser should only be rendering what's onscreen. The pages I used this on are graphically heavy with a lot of complex multi-layer effects, and this doesn't seem to have a noticeable performance impact.

Seems like many mobile browsers have excessively optimized rendering, which leads to quirky failures with few well documented fixes. Forcing repaints was the only working fix I found.

I tried other, slightly less aggressive, documented methods of forcing repaints. Like adding some text to the page (invisibly) after scrolling stops for 200ms, and such. Nothing worked though, thus my animate-the-entire-page-forever hack.

In your case, some of those other hacks may work better. This article outline all the various things that cause repaints/reflows so you could try doing some of these things via script.

like image 175
Veneseme Tyras Avatar answered Nov 20 '22 13:11

Veneseme Tyras