Fast forward again to the current, final implementation. The navigation needed to have a sticky footer in the bottom of the screen on mobile, and needed to appear from the left, which was easily achieved by having the navigation container positioned fixed, transformed to the left and given a height of 100vh, all the while being contained within the same structure we were using on desktop. Piece of cake. Or so I thought.

It turns out, that vh, i.e. viewport height, apparently doesn’t mean viewport height. Instead, it means whatever the specific vendor decides to specify as the viewport, regardless if it is the actual viewport (yes, we can have a debate regarding how a viewport should be defined, but if you redefined the term, why even bother calling it that anymore). On iOS Safari, which in this case means Webkit, this results in the viewheight being the height of the browser window, from top to bottom, regardsless of native overlays, e.g. the URL bar or the bottom navigation bar.

“But David, this can be migitated by the user scrolling a little inside the body element”. Yup. That’s what we originally though so too. But although it definitely makes the 100vh actually be 100% of the viewport, we had another problem: When tapping in the area previously covered by the bottom bar, the tap instead propagated directly to the native overlay and showed it again.

This is a deeply unintuitive way of interacting with the web, or at least I feel so, and so did the rest of my team. If something is shown in the viewport, then clicks directed towards those elements shouldn’t be hijacked by native behaviour. To me, this implementation is almost as bad, if not worse, than the tap delay. Imagine that the same thing happened in an app. It would be beyond frustrating, and while I know that web apps don’t yet have a priority within Apple, at least Google, i.e. the Chrome team, has a specific focus on progressive web apps.

Apple (I’m pointing out Apple, because as far as I know they were the first to implement this behaviour) even has a toolbar as one of their design guidelines, albeit for iOS.

This is the bar proposed in the Apple design guidelines for how to present more specific user interaction.

I may be violating their design guidelines in the above solution, but imagine that I had actually created a toolbar according to their specifications for my web app. This would be completely obstructed if I was using 100vh to define the height of it’s container.

We ended up, in order to fix this, with a tiny bit of JavaScript to ensure that the bottom menu item is actually clickable:

What I find most interesting is that this actually triggers. How come that the native controls trigger the resize event on the window, when the viewport apparently doesn’t get updated? This is fundamentally confusing behaviour, and the code above requires an extra level of commenting to explain why it was implemented (or maybe just link to this article…) to ensure that it doesn’t get deleted in future refactoring.