T

vrem

(vertical rem)

vrem is a simple css hack that turns 1rem into 1 line making it easy to play with a vertical grid in the browser. Adding a line and a half margin to an element is as simple as margin: 1.5rem. This makes it easy to nudge elements around in css without a calculator or pre-processor.

tl;dr

The trick is to hijack the html font size with your desired line height. Then you define the font size in the body relative to the line height instead of the other way around. One rem becomes one line and the rest of your type can be sized in ems as usual.

Calculate these two values:
$rootLineHeight = line height in px / 16
$rootFontSize = font size in px / line height in px
and plug them in here:

html { font-size: $rootLineHeight; }
body { font-size: $rootFontSize; }
h3 {
	font-size: 2em;
	line-height: 2rem; /* 2 lines */
	margin-bottom: 1.5rem; /* 1.5 lines */
}

The Problem with Em and Rem

There are two core sizes at the heart of responsive typography: the base font size which drives the size of all the typographic elements on the page, and the line height which drives the vertical rhythm or what we often call the baseline grid.

Typically, we set our base font size for a document and then all of the other sizes and measurements including the line height and vertical grid are declared in ems relative to that font size.

But this approach makes for awkward math, styles that are difficult to understand at a glance, and designs that are difficult to change or experiment with. You can see this in the simple css below:

body {
	font-size: 1.125em; /* 18px */
	line-height: 1.4444444em; /* 26px */
}
h1 {
	font-size: 2.6179240000000004em;
	line-height: 1.1035037261925436em;
	margin-bottom: 0.8276277946444076em; 
}

What's the line height of h1? Is it one line, two lines, a line and half? How big are the margins? How quickly could you tighten up the bottom margin by half a line and maintain the vertical rhythm?

Working with rems cleans things up a bit:

html {
	font-size: 1.125em; /* 18px */
}
body {
	font-size: 1rem;
	/* line height 26px */
	line-height: 1.4444444rem; 
}
h1 {
	font-size: 2.617924rem;
	line-height: 2.8888888rem;
	margin-bottom: 2.166666666rem; 
}

Now the line height and margins are relative to the root. If you know the root line height is 1.444rem, you can figure out fairly easily that h1 is two lines high. But what if you wanted the margin to be a line and a half? Or what if you wanted to experiment with a new font size and line height for the page? It's still a big pain.

Tapping your foot to the beat

For the growing number of us that design in the browser instead of photoshop and begin working with html and css long before designs have been finalized, these kinds of calculations can become a real gumption trap.

When you're working with a vertical grid, you don't care about the font size, you're thinking in multiples or fractions of lines.

The problem is that, even with rem, the vertical rhythm is expressed relative to the base font size. But when you're working with margins and paddings and borders or anything else tied to the vertical grid, you don't care what the font size is, you're thinking in multiples or fractions of lines. Measuring the vertical grid in terms of the font size is kind of like forcing a musician to count out the beat relative to the length of the notes being played. 1

So while rem cleans things up by giving us a single root value for all of our measurements, what we really want are two root values: a root font size that can drive all of the typographic elements on the page, and a root line height that can drive the vertical rhythm. Then the css would like something this:

body {
	root font-size: 1.125em; /*18px*/
	root line-height: 1.444444em; /*26px*/
}
h1 {
	font-size: 2.617924em;
	line-height: 2 lines;
	margin-top: 2 lines;
	margin-bottom:1.5 lines;
}

CSS preprocessors like LESS can accomplish this with mixins and variables, but i wanted a pure css way to create separate root values for the text and the vertical grid.

Vertical Root Em

vrem turns ems and rems into two separate root values - em for font size and rem for the line height. Here's the trick ...

Hijack the html font-size property and fill it in with your desired line height in ems (relative to the default font size of the browser which is 16px). So if you want a line height of 22px, your hijacked html font size would be 22/16 = 1.375em. This turns 1rem into one line.

Then you declare your actual font size in the body in ems - relative to your line height. So 16px would be 16/24 = 0.66666666666rem.

That sounds pretty messy at first, but the rest of the css becomes wonderfully easy to read ... and all you've really done is define your font size relative to the line height instead of the other way around:

/* line height: 26px (26/16) */
html {font-size: 1.625em;}

/* the base font size 18px
relative to our line height (18/26 ) */
body { 
	font-size: 0.6923076923076923rem;
} 

/* 1 rem = 1 line */
body {line-height: 1rem;}

h1 {
	font-size: 2.617924em;
	line-height: 2rem; /* 2 lines */
	margin-bottom: 1.5rem; 
}

Since you declared your font size in the body, the sizes of all of your typographic elements, like headings, can be declared exactly as they normally would be: relative to the base font size in ems. And all of the elements tied to the vertical grid, like padding and margins and line heights, no longer require any fancy calculations.

Hijacking the html font size and using it for our line height makes 1rem equal to one line

Vertical grids made easy

Once 1rem equals one line, multiples and fractions of lines become trivial to work with. Want to add one and a half lines of margin below a header: 1.5rem. Want a quarter of a line of padding inside a button: 0.25rem.

Nudging measurements around in css without having to break out a calculator takes a lot of the friction out of designing in the browser. And it eliminates all the grunt work of designing with a finer resolution vertical grid - like half a line height.

It's a very simple hack, but Typogasm can handle all of the calculations for you if you'd rather just concetrate on beautiful type.

Your mileage may vary

I'm been using vrem for years on my own projects and so far haven't run into any problems. But I haven't tested it across every conceivable browser. All of Typogasm is using vrem, including this page.

Keep in mind that since you're using ems instead of rems for your typographic elements, you'll still have the nesting issues that rem was meant to solve. But the traditional workarounds still apply:

li li {font-size:1em}

  • 1. Kind of. The musical analogies that get used in typography often get stretched too far, and I'm bending this one a bit to make a point. Typographic scales are similar in some ways to musical scales, but they are also very different. The relationship between pitch and beat is not the same as the relationship between font size and vertical rhythm in typography. A topic for another article.