🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.
CSS MASTER CLASS /// VISUAL ENGINEERING /// LAYOUT DESIGN /// ANIMATION LAB /// CSS MASTER CLASS /// VISUAL ENGINEERING ///

Dynamic Viewport Units: Solving 100vh On Mobile

Understand why traditional 100vh fails to match the actually-visible viewport on mobile browsers with collapsing chrome, what the three new dynamic viewport unit variants (svh, lvh, dvh) each guarantee, and how to choose between them deliberately.

Total XP: 0|💻 css XP: 0

Skill Matrix

UNLOCK NODES BY LEARNING NEW TAGS.

Dynamic Viewport Units

Solving 100vh on mobile, finally.


🚀 LEVEL UP TO SENIOR:Unlock 500+ Advanced Practical Challenges & Exercises.
🎓 COURSERA PARTNER:Earn professional Google, Meta, and IBM certificates to supercharge your resume.

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.

.hero { height: 100vh; }
/* Calculated against the largest possible viewport, not the current one */
localhost:3000
⚠ Chrome-Blind Calculation100vh assumes browser chrome is collapsed, which is often wrong on mobile — leading to cut-off content or unwanted scrolling.

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.

.hero { height: 100dvh; }
/* Tracks the real, currently-visible viewport height, live */
localhost:3000
✓ Accurately Matches Reality100dvh always reflects the actual currently-visible viewport height, updating live as mobile browser chrome expands and collapses.

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.

.modal { height: 100svh; } /* stable, never resizes */
.hero { height: 100dvh; } /* accurate, can resize */
localhost:3000
Interactive full-screen UI → prefer svh (stable)
Passive hero/banner → prefer dvh (accurate)

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

ChromeSupported

Fully supported.

FirefoxSupported

Fully supported.

SafariSupported

Fully supported.

EdgeSupported

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

THE BUG

A full-height mobile hero section requires scrolling to see its bottom content, even though it looks fine on desktop.

THE FIX

Replace height: 100vh with height: 100dvh so the height accurately tracks the actual visible viewport as mobile browser chrome expands and collapses.

THE BUG

A full-screen modal visibly resizes while a user is scrolling content inside it.

THE FIX

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;
}

Interview Prep

?Frequently Asked Questions

Pascual Vila

Pascual Vila

Frontend Instructor // Code Syllabus

Common Pitfalls & Errors

The Error //

Using 100vh for a full-height mobile section, causing cut-off content

/* Wrong on mobile */ .hero { height: 100vh; } /* Correct */ .hero { height: 100dvh; }

The Solution //

Switch to 100dvh so the height accurately tracks the real, currently-visible viewport as browser chrome toggles.

The Error //

Using dvh for interactive full-screen UI, causing distracting resizing mid-interaction

/* Can resize distractingly during interaction */ .modal { height: 100dvh; } /* Stable */ .modal { height: 100svh; }

The Solution //

Use svh instead for stable, non-resizing full-screen interactive elements like modals.

Lesson Glossary

[01]dvh

Dynamic viewport height, tracking the real visible viewport in real time.

Code Preview
100dvh

[02]svh

Small viewport height, assuming browser chrome is fully expanded.

Code Preview
100svh

[03]lvh

Large viewport height, assuming browser chrome is fully collapsed.

Code Preview
100lvh

[04]Browser Chrome

The browser's own UI (address bar, toolbar) surrounding page content.

Code Preview
Address bar, toolbar

Continue Learning