Generated Content by David Storey

Responsive viewport units (vw, vh, and vmin)

With all this new fangled talk of responsive web design, its about time that we had a poster child CSS unit to go with it. So move over em, CSS3 Values and Units introduces a bunch of new viewport units that are getting ready for their time in the limelight.

Motorola recently implemented support for these viewport length units and they’ve now found their way into Chrome Canary, so we can now start to experiment with them. They are also supported in IE9, although the vm unit has been updated to vmin since then.

Introducing vh, vw, and vmin

The vh unit stands for viewport height, vw for Volkswagen viewport width, and vmin represents whichever of vh or vw is the shortest length.

The values used can be somewhat confusing if you’ve not used these units before, as 1vh represents 1% of the current viewport (the content area of the browser window) height, rather than 100% as you may expect. Therefore if you want an element to be the full height of your viewport you should set it to 100vh. As you would expect, vw works exactly the same way as vh units.

If you have a widescreen monitor and your browser window is set to full screen, the width would be wider than the height. In this case the vmin unit would be the same as the vh unit.

The viewport units are dynamic rather than static, so if you resize the browser window, the computed value of the units will also change. If for example your browser window is 1000px wide, and element with a width of 10vw would be 100px wide. If you shrink the browser window to only 100px wide, the width of the element would resize with it to 10px wide.

A responsive example

One of the big issues with using multi-column layout is that you need to endlessly scroll up and down the page to read each column if the height is taller than the viewport. The viewport units mitigate this somewhat, as you can set the hight of the element with multi-column applied to it to be smaller than the viewport height (but remember to take the margins into account). You still have the issue of horizontal scrolling if you restrict the height, but this may be an ok solution if you’re designing for something like a tablet device.

I’ve created a quick example that uses this technique. Go and check out my multi-column responsive viewport example in Chrome Canary to see it in action. It should look something like the following screenshot:

As the scrollbar is hidden by default in Mac OS X Lion, its a bit difficult in this example to see that the text is scrollable horizontally.

Setting the width and height to respond to the viewport size is trivial with the vh and vw units:

article > section {
    column-width: 22rem;
    column-gap: 2.6rem;
                
    height: 80vh;
    width: 80vw;
        
    overflow: scroll;
}

This sets the height to be 80% of the viewport height, and the width to be 80% of the viewport width. The width of each column is set to be ideally 22rem (220px in this case) wide, but the browser can adjust this as needed. Finally overflow is set to scroll so that additional columns are hidden and can be scrolled into view, rather than overflowing to the right, and potentially overlapping any element that we place there.

I also set some margins on the body element to give some breathing space. This also scale with the viewport size, to be 2% of the viewport height top and bottom, and 10% of the width left and right:

body {
    margin: 2vh 10vw;
}

With this, you have a truly responsive design (at least with a simple example such as this), without even touching media queries. Imagine what untold powers they will bestow on you when you combine them? Add Flexbox to the mix, and we’ll really be cooking on gas.