Exploring CSS Viewport Units Beyond vw and vh

Abstract image used to represent Exploring CSS Viewport Units Beyond vw and vh
Image by Erik Mclean.

In Brief

vw and vh size against the viewport width and height; vmin and vmax follow the smaller or larger dimension, whilst vi and vb follow the writing mode. The sv*, lv* and dv* families model small, large and dynamic viewport states. Mobile browser controls can still affect the result, so choose the unit for the layout behaviour you need and test it on real devices.

When working with responsive web designs, most developers should be familiar with vw (viewport width) and vh (viewport height) units. These provide an intuitive way for us to size elements relative to the browser window, and means we can easily do things like fullscreen takeovers simply by setting an element's width to 100vw and height to 100vh (although when it comes to iOS, this isn't always as straightforward as it perhaps should be).

But, CSS offers a wide range of additional viewport units that don't get nearly as much attention, including some designed for writing modes and others tailored for precise handling of viewport quirks. Here, I intend to cover the essentials of vw and vh, and introduce you to some of the lesserknown viewport units like vmin, vmax, vi, and vb, and talk you through the new s, l, and d modifiers, which can make our CSS even more powerful.


The Basics: vw and vh

I've written about using vw and vh units before, but nevertheless, a quick overview here will help set the foundations for the rest of this article. So:

vw (Viewport Width)

Represents 1% of the viewport's width. For example, if the browser window is 1000px wide then 1vw is 10px, 2vw is 20px, etc.

vh (Viewport Height)

Represents 1% of the viewport's height. For example, if the browser window is 800px tall then 1vh equals 8px.

Example Usage:

.container {
  width: 50vw; /* 50% of the viewport width */
  height: 75vh; /* 75% of the viewport height */
  background-color: lightblue;
}

These units are great for creating layouts that scale with the viewport. However, when browser UI elements (e.g., address bars) or different writing modes come into play, vw and vh can be limiting.


Beyond vw and vh: Additional Viewport Units

The CSS Values and Units draft extends viewport sizing to writing modes and changing browser controls. In December 2021, these newer units are something to follow and test for support, rather than assume every browser can use. Keep a working fallback when experimenting with them.

vmin and vmax

Unlike vw and vh which are explicitly tied to one axis or the other of the viewport (width or height), vmin and vmax represent 1% of either the smaller or larger of the two dimensions.

  • vmin represents 1% of the smaller dimension (either width or height).
  • vmax: Represents 1% of the larger dimension (either width or height).

With these, you can create elements that maintain their proportions across devices, regardless of things like device orientation.

For example, this element will always be 20% of the smaller viewport dimension in width, and 20% of the larger viewport dimension in height:

.box {
  width: 20vmin; /* 20% of the smaller viewport dimension */
  height: 20vmax; /* 20% of the larger viewport dimension */
  background-color: coral;
}

vi and vb

These follow the writing mode: vi measures 1% of the viewport's inline axis, whilst vb measures 1% of its block axis.

  • vi (Viewport Inline): Represents 1% of the viewport's inline axis.
  • vb (Viewport Block): Represents 1% of the viewport's block axis.

In a vertical writing mode such as writing-mode: vertical-rl, the inline axis runs vertically. Righttoleft text in a horizontal writing mode still has a horizontal inline axis: changing direction alone does not swap width and height.

For example:

.article {
  width: 50vi; /* half the viewport size along the inline axis */
  height: 75vb; /* 75% of the viewport size along the block axis */
  background-color: lightgoldenrodyellow;
}

In horizontal writing modes, vi follows the viewport width and vb its height. In vertical writing modes, those axes swap. That lets the sizing follow the writing mode without a separate rule for each language preference.

sv, lv, and dv Modifiers

Much like you can modify em units with an r to make them rem units, viewport units also have a set of their own modifiers which can be combined with the units to better handle variations in the browser UI.

  • Small

    (s) measures 1% of the small viewport size, with dynamic browser interfaces in their expanded state.
  • Large

    (l) measures 1% of the large viewport size, with dynamic browser interfaces in their retracted state.
  • Dynamic

    (d) measures 1% of the dynamic viewport size, which changes as those browser interfaces expand or retract.

For example:

.hero {
  height: 100svh; /* full height of the small viewport */
  width: 100lvw; /* full width of the large viewport */
}

.popup {
  max-height: 50dvh; /* half the height of the dynamic viewport */
}

The choice is a tradeoff. Small viewport units stay stable as browser controls open and close, but can leave spare space when the controls retract. Large viewport units also stay stable, but content can be obscured when controls expand. Dynamic units follow those changes and can resize the content during scrolling. None guarantees both a fixed size and an unobscured fit in every state.


When to Use Which Viewport Unit

  • vw and vh are great for basic, responsive layouts.
  • vmin and vmax are ideal for proportional designs based on the viewport's smallest or largest dimension.
  • vi and vb should be used for layouts that need to adapt to different writing modes or internationalisation.
  • s, l, and d modifiers are best used for precise handling of viewport changes caused by dynamic browser UI elements.

Wrapping Up

Viewport units are a cornerstone of responsive design, and CSS offers far more than just percentagebased units based on screen width and height (vw and vh). By leveraging units like vmin, vmax, vi, and vb, along with the s, l, and d modifiers, we can create layouts that are not only flexible but also adaptable to global audiences and modern browser quirks.

Key Takeaways

  • vw and vh represent 1% of the viewport width and height, perfect for responsive designs.
  • vmin and vmax adapt based on the smallest or largest dimension of the viewport.
  • vi and vb provide flexibility for different writing modes.
  • s, l, and d modifiers refine viewport units for handling browser UI variations.

Understanding these units allows us to build more sophisticated, adaptable interfaces and ensures that our web experiences remain robust and userfriendly across devices, screen dimensions, and contexts.

Postscript

November 2022: The newer viewport units reached the major browser engines during 2022: Safari 15.4, Firefox 101 and Chrome 108 added support. That rollout came after this article's original December 2021 publication. For new work, choose svh, lvh or dvh according to the behaviour you want, keep fallbacks for older browsers, and test real mobile browser controls.

Have a complex web platform issue?

Tell me what is blocked, what has changed, and what needs to be true after the fix. I'll come back with a practical next step.