Get a better view: The Magic of Viewport Units

Viewport Units are a fine addition to the new CSS3 properties and allow us to calculate dimensions according to the actual size of the viewport, instead of the parent element (as it’s always been so far). There is a new precious tool for better and easier responsiveness that leads the way to a new approach, not only to the process of layout building, but also to web typography. 


Viewport width and height: an overview

Viewport Width (vw) and Viewport Height (vh) are units that define a relationship to the width or, respectively, the height of the viewport, and each of these units represents 1% of the total viewport . So we have:

    1vh = 1% viewport height
    1vw = 1% viewport width
    100vh = viewport height
    10vw = 10% viewport width

At first glance, one might wonder whether there is any difference between width= 100vw and width= 100%; of course there is, and it’s a pretty big one. An element that has 100% width is exactly as wide as its container while another one with a width of 100vw will always have the size of the viewport.

This becomes more clear when considering the height, since a block level element, for its default behaviour, will widen itself as much as possible, but it will be just high enough for the content to fit in. An element with a height of 100% will cover the viewport only if its parent does, something you can achieve by assigning a 100% width to the html and body element; an element with a height of 100vh will always extend to the browser window’s height. 

There’s an intuitive and quick use for Viewport Height, namely if we need a series of layers with a nice background image that covers the viewport entirely: just setting the layers' height to 100vh plus a combination of background-size: cover; and background-position: center; will give us what we want on mobile as well without major adjustments.

But wait, there’s more: vmin and vmax

Vmin and vmax complete the specification of the Viewport Units. They express a percentage of the viewport’s largest (vmax) or smallest (vmin) side. Vmax is always the longest side of our window and it will be the width when we keep a mobile phone in landscape mode but, if we put it in portrait mode, vmax will become the height.

A headline that really fits

It’s a popular trend to have one big presentation headline just on the homepage of a website, but it always requires heavy resizing when we switch to mobile phones. In addition, one should provide an extra rule for the mobile screen’s orientation, since a headline that fits when we are in landscape view, will definitely be too large when we put the phone in portrait mode. 

We can solve this problem by binding the headline’s font-size to vmin; since it’s always the shortest side of the viewport, it will fit the screen even if we change the orientation. It’s highly recommended to use vmin instead of vmax since the former has better support. 

Viewport-based typography: a quick note

With the many devices and resolutions we need to consider in our development flow, using a fixed font size is certainly not a good idea, since it will inevitably be too small or too big for a large number of users. Usually, web designers solve this problem with media queries, setting up breakpoints for mobile, small screens and big ones: it’s an approach that usually brings positive results but it’s not easy to maintain, and it would be nice to have a rule that can define a size that fits all.

Viewport Units can surely aid on that topic, since they are bound directly to the viewport size, but binding the font size directly to a fixed percentage of the viewport (1%, for example) does not lead to optimal results. If we define font-size: 1vw, it will be definitely pretty good at medium resolutions, it’s 16px at 1600x1200, but totally unreadable on mobile when it’s shrunk to less than 4px. It would be much better if we could define a base font size and increase it according to the viewport:

body { font-size: calc(12px + 0.3vw) }

This returns a font size of roughly 13px on mobile, 15px on a 1024px resolution and 17px on a screen that is 1680px wide. However, some compatibility issues related to window resizing have been reported, so the following equivalent statement should have better support:

body { font-size: calc(75% + 0.3vw) }

How safe are they for today’s use?

Nowadays, almost every CSS3 property has a good overall support, and viewport units follow this trend with only IE8 and old iOS and Android versions (5.1 and 4.3, respectively) that lack full support. However that doesn’t mean that within the supported browsers everything is fine: the most serious issue relates to the scrollbars that are erroneously computed into a 100vw declaration (Firefox doesn’t have this issue) and this often requires an overflow-x: hidden fix. In addition, vmax is unsupported by IE9 and other more recent browsers (noteworthy is that it’s sister property, vmin, is fully supported).

The availability of the exact viewport height and the possibility to use it in production has always been one of the most awaited CSS features; combining calc() and viewport units helps us climb one step further towards full layout control. With the aid of Flexbox, and the upcoming CSS Grid, we could consider the process almost complete: time to move on to a new challenge!