What are viewport units (vh, svh, lvh, dvh)?
Definition Viewport units are CSS lengths relative to the size of the viewport: 1vw is 1% of its width and 1vh 1% of its height. Because phone toolbars collapse while scrolling, CSS also defines svh (small viewport, toolbars shown), lvh (large viewport, toolbars hidden) and dvh (dynamic, whatever is visible now). On phones vh equals lvh. The new units work in Safari 15.4, Chrome 108 and Firefox 101 and later.
How to fix it: 100vh on Mobile Safari: dvh, svh and lvh Explained
How do viewport units work?
On desktop the viewport has one size, so 100vh is simply the window height. On a phone, Safari's toolbar and Chrome's address bar shrink as you scroll, and the visible height grows by a few dozen pixels. Recalculating vh on every scroll would make pages jump, so browsers fixed vh to the largest size. The result is the well-known bug: a 100vh hero is taller than what you can see when the page opens.
CSS Values and Units Level 4 added three variants of every viewport unit:
| Unit | 1 unit is 1% of | Changes while scrolling? |
|---|---|---|
svh, svw | the small viewport, with browser bars shown | No |
lvh, lvw | the large viewport, with the bars retracted (same as vh on phones) | No |
dvh, dvw | the dynamic viewport, what's visible right now | Yes |
There are also vmin/vmax (the smaller or larger side) and logical vi/vb units, each with s, l and d versions.
svh vs dvh: which one?
- svh for a hero or section that must fit on first load. It never resizes, and when the bars collapse a little extra page shows.
- dvh for an app-like shell or overlay that should always fill exactly the visible area. It resizes as bars move, which costs layout work during scrolling, so don't use it for big parts of a normal page.
- lvh for backgrounds that must never show a gap.
Example
.hero {
min-height: 100vh; /* fallback for older browsers */
min-height: 100svh; /* fits with the toolbars visible */
}
None of these units shrink for the on-screen keyboard by default: on iPhone and in Chrome since version 108, the keyboard only shrinks the visual viewport. Chromium browsers resize the layout instead if the viewport meta tag has interactive-widget=resizes-content.
In MobileCheck
MobileCheck has no check for viewport units. Its emulated browsers have no collapsing toolbar: the bars' space is already subtracted, so vh, svh, lvh and dvh all resolve to the same height. To see the difference, test on a real iPhone or Android phone, or in Apple's iOS Simulator.