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.