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:

UnitWhat it tracks
svh / svwSmall viewport — assumes UI chrome (address bar, nav) is fully visible
lvh / lvwLarge viewport — assumes UI chrome is hidden/retracted
dvh / dvwDynamic 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).