CSS Viewport Units: vh, vw, vmin, and vmax

It’s been a few years since viewport units were first introduced in CSS. They’re truly “responsive length units” in the sense that their value changes every time the browser resizes. If you’ve heard about these units before but never learned about them in detail, this article can help you out.

The Units and Their Meaning

There are four viewport-based units in CSS. These are vh, vw, vmin and vmax.

  • Viewport Height (vh). This unit is based on the height of the viewport. A value of 1vh is equal to 1% of the viewport height.
  • Viewport Width (vw). This unit is based on the width of the viewport. A value of 1vw is equal to 1% of the viewport width.
  • Viewport Minimum (vmin). This unit is based on the smaller dimension of the viewport. If the viewport height is smaller than the width, the value of 1vmin will be equal to 1% of the viewport height. Similarly, if the viewport width is smaller than the height, the value of 1vmin will be equal to 1% of the viewport width.
  • Viewport Maximum (vmax). This unit is based on the larger dimension of the viewport. If the viewport height is larger than the width, the value of 1vmax will be equal to 1% of viewport height. Similarly, if the viewport width is larger than the height, the value of 1vmax will be equal to 1% of hte viewport width.

Some Example Values

Let’s see what the value of these units will be in different situations:

  • If the viewport is 1200px wide and 1000px high, the value of 10vw will be 120px and the value of 10vh will be 100px. Since the width of the viewport is greater than its height, the value of 10vmax will be 120px and the value of 10vmin will be 100px.
  • If the device is now rotated so that the viewport becomes 1000px wide and 1200px high, the value of 10vh will be 120px and the value of 10vw will be 100px. Interestingly, the value of 10vmax will still be 120px because it will now be determined based on the height of the viewport. Similarly, the value of 10vmin will still be 100px.
  • If you resize the browser window so that the viewport becomes 1000px wide and 800px high, the value of 10vh will become 80px and the value of 10vw will become 100px. Similarly, the value of 10vmax will become 100px and the value of 10vmin will become 80px.

At this point, viewport units may sound similar to percentages. However, they’re very different. In the case of percentages, the width or height of the child element is determined with respect to its parent. Here’s an example:

See the Pen Viewport Units and Percentage by SitePoint (@SitePoint) on CodePen.

As you can see, the width of the first child element is set to be equal to 80% of its parent’s width. However, the second child element has a width of 80vw, which makes it wider than its parent.

Applications of vh, vw, vmin, and vmax

Since these units are based on viewport dimensions, it’s very convenient to use them in situations where the width, height or size of elements needs to be set relative to the viewport.

Fullscreen Background Images or Sections

It’s very common to set background images on elements that fully cover the screen. Similarly, you may want to design a website where each individual section about a product or service has to cover the entire screen. In such cases, you can set the width of the respective elements to be equal to 100% and set their height equal to 100vh.

As an example, take the following HTML:

<div class="fullscreen a">
  <p>a<p>
</div>

You can achieve a fullwidth background image section using the CSS below:

.fullscreen {
  width: 100%;
  height: 100vh;
  padding: 40vh;
}

.a {
  background: url('path/to/image.jpg') center/cover;
}

See the Pen Fullscreen Sections by SitePoint (@SitePoint) on CodePen.

Both the first and second image are taken from Pixabay.

Create Perfectly Fitting Headlines

The FitText jQuery plugin can be used to scale headlines in such a way that they take up all the width of the parent element. As we mentioned earlier, the value of viewport units changes directly based on the size of the viewport. This means that if you use viewport units to set the font-size for your headings, they’ll fit perfectly on the screen. Whenever the viewport width changes, the browser will also automatically scale the headline text appropriately. The only thing that you need to do is figure out the right initial value for the font-size in terms of viewport units.

One major problem with setting font-size this way is that the size of the text will vary greatly depending on the viewport. For example, a font-size of 8vw will compute to about 96px for a viewport width of 1200px, 33px for a viewport width of 400px and 154px for a viewport width of 1920px. This can make the font either too large or too small for it to be properly readable. You can read more about properly sizing the text using a combination of units along with the the calc() function in this excellent article about viewport unit-based typography.

See the Pen Perfectly Fitting text by SitePoint (@SitePoint) on CodePen.

Easily Center Your Elements

Viewport units can be very helpful when you want to put an element exactly at the center of your user’s screen. If you know the element’s height, you just have to set the top and bottom value of the margin property to be equal to [(100 - height)/2]vh:

.centered {
  width: 60vw;
  height: 70vh;
  margin: 15vh auto;
}

See the Pen Easily Center Your Elements by SitePoint (@SitePoint) on CodePen.

However, nowadays we can use Flexbox or CSS Grid to center elements, both vertically and horizontally.

Things to Keep in Mind

If you decide to use viewport units in your projects, there are a few things you should keep in mind.

Be careful when setting the width of an element using viewport units. This is because when the overflow property on the root element is set to auto, the browsers will assume that the scrollbars don’t exist. This will make the elements slightly wider than you expect them to be. Consider markup with four div elements styled as follows:

div {
  height: 50vh;
  width: 50vw;
  float: left;
}

Normally, you’d expect each div to occupy a quarter of the available screen. However, the width of each div is computed with the assumption that there is no scrollbar. This makes the div elements slightly wider than the required width for them to appear side by side.

See the Pen Scrollbars and vw by SitePoint (@SitePoint) on CodePen.

Setting the divs’ width from 50vw to 50% will solve this problem. The conclusion is that you should use percentages when setting width for block elements so that the scrollbars don’t interfere with the computation of their width.

A similar issue can also occur on mobile devices because of the address bar which may appear or disappear depending on whether the user is scrolling or not. This will change the viewport height and the user will notice sudden jumps when viewing the content.

Browser Support

Based on the data available on Caniuse, it seems that every major browser supports these units. However, there are still a few bugs and issues that you should be aware of when using viewport units. For example, in Firefox there’s a documented bug where 100vh has no effect on any element with its display property set to table. Again, Chrome doesn’t support viewport units for border widths, column gaps, transform values, box shadows or in calc() until version 34. Check out Caniuse for a full list of known bugs.

Conclusion

In this article, we’ve briefly covered the meaning, applications and browser support of viewport units. If you know about any other interesting application or browser issue in relation to these units, why not tell us about them in the forums.

Take your CSS skills to the next level with our book CSS Master, 2nd Edition by Tiffany B. Brown – covering CSS animations, transitions, transformations and much more.