Viewport Sized Typography

CSS3 has some new values for sizing things relative to the current viewport size: vw, vh, and vmin. It is relevant to bring up now, because it’s shipping in Chrome 20 (canary at the time of this writing). And not behind a flag, it just works. Production usage isn’t quite there, but it will be soon enough.

Why is this awesome?

There are many reasons. Here are two:

  1. There is a such thing as a comfortable line length for reading text on screens. I don’t want to kick a hornet’s nest, but let’s say its around 80 characters. These units allow you to get it feeling perfect and then have that experience scale to any size screen.
  2. They allow you to tightly couple the size relationship of, say, a typographic header and the content it goes with. Like your classic Trent Walton style blog post.

How they work

One unit on any of the three values is 1% of the viewport axis. “Viewport” == browser window size == window object. If the viewport is 40cm wide, 1vw == 0.4cm.

For use with font-size, I guess it’s one “letter” that takes on that size, but as we know, in non-mono-spaced fonts the width of a letter is rather arbitrary. I find you just need to tweak around with the values to get it how you want it. Which is basically what we do anyway, right?

1vw = 1% of viewport width
1vh = 1% of viewport height
1vmin = 1vw or 1vh, whichever is smaller

Using them

Easy cheezy:

h1 {
  font-size: 5.9vw;
h2 {
  font-size: 3.0vh;
p {
  font-size: 2vmin;


Here’s a video of a simple layout using vw units so the typography.

Check out the demo yourself (see browser support).


The support is there in Chrome 20, but it fails in one rather significant way. When the browser window is resized, the font doesn’t adjust itself according to the new viewport size. The spec says:

When the height or width of the viewport is changed, they are scaled accordingly.

I bugged it. Perhaps not a huge disaster as it’s pretty much just us design nerds that go around adjusting browser windows, but still. The font does adjust on a fresh page load.

To fix this issue (allow resizing without page refresh) you need to cause a “repaint” on the element. I used jQuery and just fiddled with each elements (irrelevant, in this case) z-index value, which triggers the repaint.

causeRepaintsOn = $("h1, h2, h3, p");

$(window).resize(function() {
	causeRepaintsOn.css("z-index", 1);

Browser Support

Chrome 20+ & IE 10+

I tried Opera Next (12), Safari 5.2, and Firefox Beta (13) and no dice.

Not just font-size

For the record, these are just units. Just like em, px, whatever. You can use them on anything, not just font-size.

I think font-size is the most compelling use case, since things like margin, padding, and width can already essentially react to browser window size by using % units. There is the case where perhaps a more deeply-nested element needs to react to the browser window size instead of its direct parent size.

Using it now

Native usage

You’ll at least want to provide a fallback:

h1 {
  font-size: 36px; /* Some tweener fallback that doesn't look awful */
  font-size: 5.4vw;

Testing for support

Modernizr doesn’t have a test for it yet, but you can test for it yourself by using some throw-away element that you see to some narrow width in CSS but then re-set to 100vw in JavaScript, then measure to see if the width of it is equal to window.width. Something like:

var testEl = $("#vw-test");

var viewport = $(window);

  width: "100vw"

if (testEl.width() == viewport.width()) {
} else {

Mimic the functionality with FitText.js

This idea of binding the overall width of a header with the width of its parent element is exactly what FitText.js does. Only it does it through fancy JavaScript and math and spans and stuff. Theoretically, you could run the test and use Modernizr.load to load up FitText.js if no support is detected.

So yeah

What do you think? Are you into it? Got some ideas on how to use it?

Viewport Sized Typography is a post from CSS-Tricks

This entry was posted in Article, Syndicated. Bookmark the permalink.

Comments are closed.