CSS Viewport Units: svh, lvh, dvh - Solving Mobile Browser Issues
The Problem with vh on Mobile
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.
Three New Units
| 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 |
Visualization
┌────────────────────────┐ ← 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 scroll
When to Use Each
svh — safe height
Best 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 */
}
lvh — maximum height
Use when you want to fill all available space with the navigation hidden — hero sections, full-screen banners:
.hero {
min-height: 100lvh;
}
dvh — dynamic height
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 */
}
Comparison with Classic 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 |
Equivalent Units for Width
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
Browser Support
All three units are supported in all modern browsers since 2022–2023:
- Chrome 108+
- Safari 15.4+
- Firefox 101+
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.