Few CSS bugs have been as widely complained about as '100vh doesn't work right on mobile'. Dynamic Viewport Units are a direct, purpose-built response to that exact problem.
1Mobile Browser Chrome: The Root Cause
Desktop browsers have a mostly-fixed chrome (toolbar, tabs) that doesn't change size as you scroll a page, so 100vh reliably matches the visible content area. Mobile browsers are different by design: to maximize visible content, they collapse the address bar and toolbar as the user scrolls down, then expand them again when scrolling up or reaching the top — the actual visible viewport height genuinely changes as this happens.
Traditional vh was specified before this behavior was common, and browsers implemented it as a calculation against the *largest possible* viewport size — essentially assuming the chrome is always collapsed. This means 100vh frequently reports a height larger than what's actually visible when the chrome is expanded, causing bottom content to be pushed off-screen or an unwanted scrollbar to appear.
2Three Explicit, Purpose-Built Variants
Rather than trying to redefine what plain vh means (which would break countless existing sites relying on its current behavior), CSS introduced three new, explicitly-named units. svh (small viewport height) always assumes the browser's UI is at its largest, most expanded state — the smallest, most conservative guaranteed viewport size. lvh (large viewport height) assumes the UI is fully collapsed — essentially matching the traditional vh behavior. dvh (dynamic viewport height) is the genuinely new capability: it actively recalculates in real time as the actual visible viewport changes while the user scrolls and the browser chrome expands or collapses.
The explicit naming is deliberate — each unit tells you exactly what assumption it's making, rather than leaving that assumption implicit and unclear the way plain vh's mobile behavior historically was.
3Choosing Between dvh And svh Deliberately
dvh is the most visually accurate option, but its live-updating nature has a real trade-off: a full-height element using 100dvh will genuinely resize, however subtly, as the user scrolls and the browser's chrome toggles — for a simple hero section this is usually imperceptible and desirable, but for something like a full-screen modal with interactive content, a resize mid-interaction can feel jarring or even shift a button out from under a user's finger.
svh avoids this entirely by locking to the smallest guaranteed viewport size (chrome fully expanded) and never changing afterward — content sized with 100svh is guaranteed to fit within the visible area at all times and will never resize, at the cost of not using every available pixel when the chrome happens to be collapsed. The right choice depends on whether visual accuracy or interaction stability matters more for that specific piece of content.
4Step-by-Step Breakdown
The '100vh On Mobile' Problem, Finally Solved. 100vh was supposed to mean 'exactly the height of the visible viewport'. On mobile browsers, it usually doesn't — the address bar and toolbar collapse and expand as you scroll, and traditional vh doesn't track that live change, causing content to overflow or leave awkward gaps. Dynamic Viewport Units were built specifically to solve this.
Why 100vh Fails On Mobile Browsers. Mobile browsers show and hide their address bar and toolbar as the user scrolls, changing the actually-visible viewport height dynamically. Traditional vh is calculated against the *largest possible* viewport (with browser chrome collapsed), so 100vh frequently exceeds the space genuinely visible when the chrome is expanded, causing bottom content to be cut off or requiring an unwanted scroll.
Why 100vh Misbehaves On Mobile. Why does height: 100vh often cause content to be cut off on mobile browsers specifically?
- →It's a rendering bug present in all mobile browsers
- →Mobile browser chrome (address bar, toolbar) expands and collapses dynamically, and traditional vh doesn't track that live change
- →vh units aren't supported on mobile browsers at all
Three New Units: Small, Large, Dynamic. Dynamic Viewport Units introduce three explicit variants: svh (small viewport height, assumes browser chrome is fully expanded — the safest, smallest guaranteed space), lvh (large viewport height, assumes chrome is fully collapsed — the old vh behavior), and dvh (dynamic viewport height, which actively tracks the real, currently-visible height as chrome expands and collapses).
Choosing The Right Unit. Which unit actively updates in real time as a mobile browser's address bar shows and hides?
- →svh — it stays fixed at the smallest possible viewport size
- →dvh — it dynamically recalculates as the actual visible viewport changes
- →lvh — it stays fixed at the largest possible viewport size
Choosing dvh vs svh Deliberately. dvh produces the most visually accurate full-height experience but can cause content to subtly resize as the user scrolls and browser chrome toggles — which is sometimes undesirable for content that shouldn't visibly shift size. svh trades perfect accuracy for total stability: it guarantees content fits within the smallest possible viewport and never needs to resize afterward.
dvh vs svh Trade-off. Why might a developer deliberately choose svh over dvh for a full-screen modal, even though dvh is more 'accurate'?
- →svh has significantly better browser support
- →svh guarantees the modal never resizes as the user scrolls and browser chrome toggles, trading some accuracy for visual stability
- →There's no meaningful reason to prefer svh in that case
Mobile Viewport Problem Solved. You now understand exactly why 100vh misbehaves on mobile browsers with collapsing chrome, what each of the three new viewport unit variants actually guarantees, and how to deliberately choose between dvh's accuracy and svh's stability based on what a specific piece of content actually needs.
Give A Fixed Fallback Height. Production code often pairs a dynamic viewport unit like 100dvh with a fixed pixel fallback for older engines.
Level Up 🚀
Advanced cheat sheets, SEO tricks, and interview prep for this topic.
Browser Support
Fully supported.
Fully supported.
Fully supported.
Fully supported.
Accessibility (A11y)
1svh's Stability Prevents Interactive Elements From Shifting Mid-Interaction On Mobile
For full-screen interactive UI like modals or bottom sheets, svh's guaranteed non-resizing behavior prevents a button or focus target from moving under a user's finger or cursor mid-scroll, which particularly benefits users with motor impairments who need stable, predictable target positions.
2Content Reserved With A Fixed Small-Viewport Height Should Still Support Overflow Scrolling For Zoomed Text
Users who increase text size or zoom may need more vertical space than even svh's conservative height provides — verify content sized with these units remains scrollable rather than clipped when text is enlarged.
SEO Implications
- 1
Fixing 100vh Mobile Overflow Bugs Directly Improves Mobile Usability Metrics
Eliminating unwanted scrollbars or cut-off content on mobile — a very common real-world 100vh bug — improves mobile usability signals that factor into mobile-specific search ranking considerations.
- 2
dvh Avoids Layout Recalculation Thrashing Compared To JavaScript-Based Viewport-Height Workarounds
Before dvh existed, many sites used a JavaScript scroll/resize listener to manually recalculate and set a custom viewport-height CSS variable — dvh replaces that with a native, browser-optimized calculation, removing the associated JS execution and layout thrashing.
Best Practices
Default To dvh For Full-Height Hero Sections And Passive Content
It provides the most visually accurate full-height experience, and the subtle resizing as chrome toggles is rarely noticeable or problematic for non-interactive content.
Default To svh For Full-Screen Interactive UI Like Modals Or Bottom Sheets
Guaranteed stability prevents interactive elements from shifting position mid-interaction, which matters far more for usability than svh's slightly more conservative use of space.
Frequent Bugs
A full-height mobile hero section requires scrolling to see its bottom content, even though it looks fine on desktop.
Replace height: 100vh with height: 100dvh so the height accurately tracks the actual visible viewport as mobile browser chrome expands and collapses.
A full-screen modal visibly resizes while a user is scrolling content inside it.
Switch from 100dvh to 100svh for the modal so its size stays fixed and stable regardless of browser chrome state changes during the interaction.
Real-World Examples
A Mobile-Accurate Full-Height Landing Hero
A landing page hero section that fills exactly the visible mobile viewport at all times, replacing a previous 100vh implementation that cut off the call-to-action button behind the browser's address bar.
.hero {
min-height: 100dvh;
display: flex;
align-items: center;
}