I know there have been multiple SO questions about this, but none of them seem to work anymore since the browser teams have made changes since those questions were asked. I'm trying to find the most up-to-date solution to this problem.
Objective
My desire is to have a fixed header stay stationary at the top for an app-like experience when using a mobile web browser, specifically when the user has focus on an input field and the virtual keyboard is showing.
Background context
Recently, the Chrome mobile team changed how they resize their layout and visual viewports for mobile web to be in alignment with Chrome on iOS and mobile Safari on iOS.
This GIF from an article by David Fedor very succinctly demonstrates the current status of most (but not all) mobile browser with regards to the visual viewport being "moved up" when the On-Screen Keyboard (OSK, aka Virtual Keyboard) is shown when a field is focused.
The biggest issue I'm facing is that I cannot get a header element to stay visually present at the top when the OSK is shown. This is a big deal when your top appbar has primary actions for a form like "Save". It makes the UX confusing, which leads to customers leaving in frustration, so this is isn't something trivial in my opinion.
I've tried the VisualViewport API that Chrome team recommended, referencing the env(keyboard-inset-height)
and that just doesn't seem to work, which makes me think I'm doing something weird with my layout such that the ENV isn't being set properly.
My code
Nothing too crazy, using CSS grid to control layout.
HTML
<html>
<body>
<div id="container">
<header id="header">header</header>
<main id="main">
main
<input type="text" />
</main>
<footer id="footer">footer</footer>
</div>
</body>
</html>
CSS style
body {
margin: 0;
}
#container {
height: 100dvh;
display: grid;
grid-template:
"header" 50px
"main" 1fr
"footer" 50px
"keyboard" env(keyboard-inset-height, 0px); // does not seem to work?
}
#header {
grid-area: header;
}
#main {
grid-area: main;
overflow-y: scroll;
}
#footer {
grid-area: footer;
}
What I get is the following 2 screenshots, the full-page one being the layout as I want it, and the 2nd one being when you focus the cursor into an input near the bottom and it "pushes" the entire visual viewport up such that the header is offscreen.
Is there any way currently to ensure that the header stays at the top of the visual viewport always? I cannot find a working solution to this at the moment after the recent Chrome updates.
svh
which may be handy. NOTE: These dimensions are much more widely available than the screenshot suggests, see caniuse – Bolero