Viewport Units in Webview = Jank
New viewport units are allegedly robust.
Primer
Standard viewport units (vh, vw) are widely understood to be unreliable. They behave differently depending on the user's device, browser, or settings.
No worries, this is why we invented additional viewport units. Problem solved, right?
The Problem
I build marketing websites for small businesses as a freelance consultant.
In Japan, LINE is the de facto messaging app. Naturally, I send websites to clients for review via LINE. When you click a link in LINE, it opens in a webview within the app.
Strangely, the svh unit wasn't behaving as expected inside that webview. The hero content was "jumping" on scroll.
<div className="min-h-[calc(100svh-6rem)]">{/* h1, image, etc. */}</div>Debugging
I discovered that the height of the webview is changing when the toolbar comes in and out of view. This happens across several applications, but I noticed it within LINE and Instagram, in particular.
I tried all the different viewport units, and none of them would solve this problem effectively.
The Fix
We take the height of the webview on mount and assign it to a CSS variable.
Then we assign the min-height of the hero section to that variable.
Webview detection
To avoid edge cases like resizing a desktop browser window and breaking the layout, we only want to apply the fix when we're inside a webview.
I wrote a utility function to help with detection, and published it as an npm package. It's a simple function that checks for the presence of certain substrings in the User-Agent string to determine if we're inside a webview.
When implemented in a Next.js application, it looks something like this:
'use client'
import { isWebview } from '@josephmcg/is-webview'
import { useEffect } from 'react'
export const ViewportHeightProvider: React.FC = () => {
useEffect(() => {
if (!isWebview(navigator.userAgent)) {
return
}
document.documentElement.style.setProperty('--initial-vh', `${window.innerHeight}px`)
}, [])
return null
}Note
Render the ViewportHeightProvider in the layout of your application.
Using the CSS variable
Adjust your hero element to use a min-height based on the initial height of the webview.
<div className="min-h-[calc(var(--initial-vh,100svh)-6rem)]">{/* h1, image, etc. */}</div>The hero content will now remain in place, despite the webview changing height upon scroll.
Closing Thoughts
In order to find this solution, I had to strip back modern CSS niceties and understand the root problem.
If we develop a deeper understanding of fundamental technologies, in this case the browser and the webview, we can find graceful and simple solutions.
Last updated
April 4, 2026