Working with REM and Viewport Sized Typography

Ready to geek out? Ready to use some typography that isn’t based on px? Enter the world of REM and Viewport sized typography. Each one is it’s own world so we are going to take it slow, go over how they are used and some of the advantages and disadvantages of them. So let’s get started and learning.

EM

To learn what rems are and how to use them, we must understand what ems are. Some of you might be already be using them in your sites.

Ems are a relative unit based on the font-size property. For example if the font size is set to 16px, 1em will be displayed at 16px. Likewise if the font size is set to 40px, 1em will now be displayed at 40px. The issue that people run into is that the value for em is inherited. Let’s see an example on how this works.

 <div class="em">
  <div>
    This is 1.5em
    <div>
      This is also 1.5em
      <div>
        Yet again, 1.5em
      </div>
    </div>
  </div>
</div>

In this markup we have various nested divs with some text. We set the base font-size at 14px.

.em {
  font-size: 14px;
}

If we apply this CSS:

.em div  {
  font-size: 1.5em;
}

Logic would tell you that since it is 1.5em, the size would be 21px (14 x 1.5 = 21). But when we render this in the browser we something interesting.

CSS Typography EM Example

The font sizes are different because the value for ems are inherited. The first div sets a new em base which is 21px. The new math on the next nested div is 21 x 1.5. In this case 31.5px.

REM

Rems are different in the way it sets the value for what its base is. REM stands for “Root EM”, meaning it takes its value from the font-size of the root element. Lets see this by example.

Very much the same markup (minus class name).

<div class="rem">
  <div>
    This is 1.5rem
    <div>
      This is also 1.5rem
      <div>
        Yet again, 1.5rem
      </div>
    </div>
  </div>
</div>

We set the same base as the first example:

.rem {
  font-size: 14px;
}

And the same paragraph font-size with the exception we are now using rems.

.rem div  {
  font-size: 1.5rem;
}

Now let’s take a look at what the browser renders.

CSS Typography REM Example

This is a much more accurate way to render elements without having to worry about inheritance issues.

Support: Firefox 3.6+, Chrome 6+, Safari 5+, IE 9+. Mentionalable lack of support on Opera Mini

As a polyfill I recommend a px font-size in your css before your font size in rem.

.rem div  {
  font-size: 21px;
  font-size: 1.5rem;
}

Viewport Sized Typography

Now lets get into the relm of the weird. Honestly I see very little use for this (for now) but they are cool to play with. The reason I see very little use for these is because they are very hard to control in a responsive design. They are hard to prevent from going too large or too small without a lot of management. If you do use them, I do not recommend using them for copy, only headers and such.

The values I am going to talk about are vw (viewport width), vh (viewport height), vmin (viewport minimum), and vmax (viewport maximum).

This is basically what they mean:

  • 1vw: 1% of viewport width

  • 1vh: 1% of viewport height

  • 1vmin: 1vw or 1vh, whatever is smallest

  • 1vmax: 1vw or 1vh, whatever is largest

This is a little hard to explain, but in the case of vw (viewport width), its value is being taken from 1% of the viewport width. So for example if the viewport (aka the browser window) is 1000px wide, 1vw is 10px (1000 x .01). Same thing with vh but with the height.

vmin and vmax act kinda like min-width/min-height or max-width/max-height but based on the viewport size.

Let look at an example. Here is the CSS code the example will be using:

.vh p {
  font-size: 2.5vh;
}

.vw p {
  font-size: 2.5vw;
}

.demo-1vmin p {
  font-size: 6vmin;
}

.demo-1vmax p {
  font-size: 2.5vmax;
}

Be sure to see the demo below to see what is going on. Make sure to resize your browser to see the changes. There is a bug with Chrome and Safari browsers that prevent the type from adjusting on the fly when the browser is resized. I have included some javascript that will repaint the text. Credit goes to Chris Coyier for this fix.

Support: Firefox 19+, Chrome 20+ (buggy), Chrome 26+ (full), Safari 6.1+, Opera 15+, iOS7 (buggy), Android Browser 4.4+, IE9+ (buggy), IE11 (full).

Demo

See the Pen AkGpr by Christopher Bishop (@cibgraphics) on CodePen.