My full screen hero uses height: 100vh. On iPhone Safari and Android Chrome the bottom button is hidden behind the browser toolbar and the page scrolls a little. How do I size to the visible area?
DEV3 Developer Forum
Why is 100vh taller than the screen on mobile browsers, and how do I fix it with dvh?
Every post is reviewed first. Usually reviewed within 24 hours.
1 reply
Cause
On mobile, 100vh equals the largest viewport, measured as if the address bar and toolbars were hidden. When they are visible the page is taller than what the user sees.
Fix: the new viewport units
Supported in all current browsers:
| Unit | Meaning |
|---|---|
svh |
small viewport: toolbars visible (smallest height) |
lvh |
large viewport: toolbars hidden (what vh means) |
dvh |
dynamic: changes as the toolbars show and hide |
.hero {
min-height: 100vh; /* fallback for old browsers */
min-height: 100dvh;
}
Use svh when you want a stable size that never overflows (no resizing while scrolling) and dvh when the element should always fill what is visible right now. A dvh element can cause layout reflows as the toolbar animates, so svh is safer for large hero sections.
Tailwind has h-dvh, min-h-dvh, h-svh, h-lvh (v3.4+).
Fixed bottom bars
For a sticky footer or bottom nav also respect the notch and home indicator:
.bottom-bar { padding-bottom: env(safe-area-inset-bottom); }
and set <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">.
Alternatives
- Avoid viewport height altogether: use a flex column with
min-height: 100%wherehtml, bodyhaveheight: 100%, andflex: 1on the main region. - The old JavaScript hack (
--vhset fromwindow.innerHeight) is no longer needed.
Pitfall
Keyboards: when the soft keyboard opens dvh does not shrink on iOS (the keyboard overlays); handle inputs with visualViewport if you need exact positioning.