Viewport units beyond vw and vh

For years, the classic viewport units have been the go-to for sizing elements relative to the browser window. vw equals 1% of the viewport’s width, and vh equals 1% of its height; give an element a width of 100vw and a height of 100vh, and it covers the viewport completely. They were joined early on by four relatives: vi and vb (based on the inline and block axes), plus vmin and vmax (the smaller and larger of vw and vh).

These units work well on desktop, but they break down on mobile. There, the viewport size depends on whether dynamic toolbars—address bars, tab bars, and similar UI—are expanded or retracted. The problem: vw and vh are static values that do not adjust when those toolbars show or hide. An element styled as 100vh tall will bleed past the visible area when the browser chrome is expanded, and only fit perfectly once the user scrolls and the toolbars retract.

The three viewports and their units

To address this, the CSS Working Group has specified distinct viewport states with their own unit families.

  • Large viewport: sized as if dynamically expanded and retracted UA interfaces are retracted. Its units carry the lv prefix: lvw, lvh, lvi, lvb, lvmin, and lvmax.
  • Small viewport: sized as if those interfaces are expanded. Its units use the sv prefix: svw, svh, svi, svb, svmin, and svmax.

Both families are fixed sizes, remaining stable unless the viewport itself is resized. There is also a third option, the dynamic viewport, which accounts for the current state of the UA UI: when toolbars are expanded it matches the small viewport; when they are retracted it matches the large one. Its units use the dv prefix (dvw, dvh, dvi, dvb, dvmin, and dvmax) and are clamped between the corresponding lv* and sv* values.

The dynamic units ship in Chrome 108, joining Safari and Firefox, which already support them.

Practical caveats

These new units are not a silver bullet. A few caveats are worth keeping in mind when using any viewport-relative lengths:

  • Scrollbars are ignored. Per the specification, viewport units assume scrollbars do not exist. On systems with classic scrollbars, an element set to 100vw will be slightly too wide.
  • Dynamic updates are throttled. The dynamic viewport’s values do not update at 60fps; browsers throttle the updates as the UA UI expands or retracts, and some may even debounce entirely depending on the gesture used.
  • Virtual keyboards are excluded. The on-screen keyboard is not part of the UA UI, so it has no effect on these units—unless you opt in to different behavior in Chrome, which allows the keyboard’s presence to resize the viewport and thus affect the units.

For deeper background, the CSS Values 4 specification covers viewport-relative lengths, and there are dedicated explainers for the layout viewport and viewport units. There is also a useful HTTP 203 episode where Bramus walks Jake through how these various viewport sizes are determined.