CSS viewport units: dvh, lvh, svh (and their *vw siblings)
vh and vw have been around forever, but mobile browsers broke them. The URL bar in Chrome/Safari shrinks when you scroll — so 100vh is taller than the visible area when the page loads, causing content to get clipped or produce unexpected scroll.
The fix landed as three new variants:
| Unit | What it tracks |
|---|---|
svh / svw | Small viewport — assumes UI chrome (address bar, nav) is fully visible |
lvh / lvw | Large viewport — assumes UI chrome is hidden/retracted |
dvh / dvw | Dynamic viewport — updates as UI chrome appears and disappears |
Same split applies to vi / vb (inline/block axis) if you need those.
Which one to use
dvh sounds like the obvious answer but it causes layout reflows as the user scrolls, which can make the page jump. Use it sparingly.
/* hero that actually fills the screen on load */
.hero {
min-height: 100svh;
}
/* sticky footer pinned to the retracted-chrome size */
.modal {
height: 100dvh;
}svh is the safe default for full-screen sections — it matches what the user sees when they first land on the page. lvh is mainly useful when you know the chrome is gone (fullscreen video, PWA display mode).
All three have been supported across Chrome, Safari, and Firefox since 2023. The oldvh still works — just be aware of what it actually measures (inconsistent across browsers, generally the large viewport).