Loading...
Loading...
The classic 100vh unit has long suffered from a well-known issue: mobile browsers (Chrome, Safari) dynamically show/hide the address bar while scrolling. vh doesn't recalculate in response — it stays fixed at one of the extreme values, causing content to either be clipped or triggering an unwanted scrollbar.
CSS Level 4 introduced three new units for precise control over this behavior.
| Unit | Stands for | Meaning |
|---|---|---|
svh | Small Viewport Height | 1% of the smallest possible viewport — when browser UI is fully visible |
lvh | Large Viewport Height | 1% of the largest possible viewport — when browser UI is fully hidden |
dvh | Dynamic Viewport Height | 1% of the current viewport size — updates in real time during scroll |
┌────────────────────────┐ ← lvh (address bar hidden)
│ │
│ Content │
│ │
├────────────────────────┤ ← svh (address bar visible)
│ [address bar] │
└────────────────────────┘
100svh — height assuming the address bar always takes up space100lvh — height with the browser UI fully hidden100dvh — live height, changes during scrollBest for fixed elements that should always be fully visible without scrolling — modals, full-screen cards:
.modal {
height: 100svh; /* guaranteed to fit, even with the address bar showing */
}
Use when you want to fill all available space with the navigation hidden — hero sections, full-screen banners:
.hero {
min-height: 100lvh;
}
Responds to the browser's actual state at any moment. Useful for sticky elements and interactive layouts, but triggers a repaint on scroll:
.sticky-panel {
height: 100dvh; /* updates when viewport size changes */
}
vh| Unit | Behavior on scroll | Mobile issue |
|---|---|---|
vh | Fixed (LVH in most browsers) | Content may be clipped |
svh | Fixed (minimum) | None |
lvh | Fixed (maximum) | None |
dvh | Dynamic | Triggers repaint |
The same three variants exist for width and combined units:
svw, lvw, dvw — width
svi, lvi, dvi — inline (horizontal in LTR)
svb, lvb, dvb — block (vertical in LTR)
svmin, lvmin, dvmin
svmax, lvmax, dvmax
All three units are supported in all modern browsers since 2022–2023:
Important:
dvh triggers layout/repaint on every viewport change (scroll, keyboard appearance). Use it only where dynamic behavior is truly needed. For static layouts, svh or lvh are preferable.
Recommendation:
For most mobile full-screen sections, 100svh is the optimal choice: content is guaranteed not to be clipped, with no repaint overhead.