Vertical Rhythm with Ems and Rems

Posted on by Jay

First off, there are already some tutorials on creating vertical Rhythm, most noticeably by Harry Roberts in his articles Single Direction Margins and Measuring and Sizing UIs and Richard Rutter’s 2006 article Compose to a Vertical Rhythm. I mostly wanted to expand on these and cover a few different examples, and more importantly some gotchas that stopped me picking this up as quickly as I should have. But first off, maybe you’ve arrived here as a skeptic. Maybe you’re scoffing pixel pies and laughing at the complicated em-based maths you’ll find here. Well, maybe I wasn’t ever that cynical, but I certainly put off looking at ems for a long time…

My Background

I’ve long resisted moving from Pixels to Ems. I was in the ‘I could do without the maths’ camp.

That’s not to say I was dogmatic about ems; I could appreciate the advantage of bumping font sizes in one go. But being frank I would rather change multiple fixed font sizes than figure out all the maths.

A few things eventually guilted me into giving them another chance, and if you’re still being bloody minded, consider the following:

  • If you’re designing responsively it’s likely you would have at least made the mental jump between designing with fixed-width containers to designing with % containers. It might have been a bit of effort to adjust, but it was worth it, right? Then you should also be questioning your beliefs on using fixed pixels for font size.
  • Question when you should ever use fixed pixels. To design responsively is to create relationships between different elements. If your viewport expands then you probably want your main container to also expand, albeit with a max-width. When your font size expands, so should your vertical paragraph padding, right? Thinking about these relationships is what convinced me to give ems another look.
  • If you look at the most influential web speakers and writers on Twitter, most, if not all of them favour ems or rems. Whilst I hate web celeb pandering, when a bunch of your web heroes hold a particular opinion you should question why that is.

Reading

Read these articles if you want to ponder futher…

  1. Flexible Foundations by Trent Walton
  2. Why Ems by Chris Coyier

Establishing a Baseline with P tags

We’ll start by just getting our vertical rhythm using just p tags. Nice and easy, hey?

The first thing you need to do is set your font-size to 100%. What this does is to make sure you’re starting off with the default font-size used by browsers, which tends to be 16px. E.g. 100% would equal 16px, 150% = 24px, 200% = 32px, etc.

If you’ve downloaded the HTML5 Boilerplate as a starting point for your project, this is done for you in their reset. I tend to repeat this rule in the main section of my style.css anyway, just for easy access.

html {
	font-size: 100%;
}

Our next step is to specify line-height. To be honest, line height is pretty arbitrary. Your typeface and the sense of space in your design will affect your judgement here, but generally 1.3 to 1.5 is considered optimal.

html {
	font-size: 100%;
	line-height: 1.5; /* Magic Number / Line-height value of 24px */
}

Using these two values we can derive our baseline figure; what Harry Roberts calls our ‘Magic Number’. This is basically what we’ll be using to set the rest of our proportions so that we create consistent rhythm.

In this case our baseline will be 24px. You get this number by times’ your font size by the line height e.g. since we are using 100% to get the browser default of 16px, in our case it would be 16px * 1.5 = 24px. This makes sense if you think about it, we’re saying ‘times our font-size of 16 pixels by 1 and a half to get the total height for the line’.

The only other thing we need to do is set a margin-bottom property on our p tags. This needs to be a multiple of our baseline i.e. a multiple of 24px in our instance. So let’s set this to 1.5rem (16 * 1.5= 24px).

FYI: We’re using rems just to avoid any nesting complications that initially put people off the em unit to begin with. If you want to know more about the difference between ems and rems, read Snook’s article.

So that’s it; we’ve created vertical rhythm with p tags. But how do we test this? There are lots of tools to do this, Dan Eden’s baseline.js for example, but I really like xScope, a Mac design app that you can use for lots of things besides testing baselines. The reason I like it over other tools is because you can set a global hotkey to toggle it off and on quickly.

In xScope you can set a baseline step by going to Guides > Guide Wizard in the menu. Then set the orientation to horizontal, bump Repeat guide to 50 and set moving gutter to the baseline figure we have i.e. 24. Make sure the gutter has been set to 0, and click ‘Create Guide’

xScope Guides

With this we can see that our p tags perfectly fit to a 24px baseline…
Vertical Rhythm with p Tags

Establishing a Baseline with H tags

Now we’re getting the hang of things, right? Other elements should be easy, but this is where you’ll hit gotcha number 1 if you’re not paying attention.

Let’s say we want to add an H2 tag. What you need to know is HTML5 Boilerplate add’s some default margins to H tags, and so does the browser naturally, therefore not only do we need to set a margin-bottom value for the h2, but we also need to reset the margin-top value.

To solve this as we style subsequent elements, you can either reset all top and bottom margins using a group selector that you start each project with, or add them one by one as you use them. I’d suggest you reset them one by one just incase you miss a style. Otherwise your reset will kill some safe defaults.

we’ll add the h2 to our vertical margin reset and pick our font-size…

/* Reset. Add elements to this Reset as you build up your vertical rhythm */
h2,
p {
	margin: 0 auto;
}

h2 {
	font-size: 2rem; /* 32px */
}

You’ll see I have put a pixel calculation next to the font-size for future reference. The thing to bear in mind is that once these first calculations have been completed, we never need to worry about them again because in later media queries we just bump the font-size up on the html selector.

You get the REM font-size by taking your chosen pixel font-size and dividing it by the initial html font-size we chose. In our case we chose the default 100% (or 16px) for our initial font-size, therefore for a font-size of 32px that would be 32px / 16px = 2rem.

Just so we have another example, if you chose 36px for your h2 font-size, this would be a rem calculation of 2.25rem (36px / 16px).

Gotcha Number 2: Always work with the font pixel size first so you can easily keep things in line with the magic number, e.g. if you arbitrary decide on on a rem figure like 2.2rem, this might give you an odd pixel calculation of 35.2px, which would throw off your vertical rhythm.

To set up the proceeding vertical rhythm we’ll need to add a margin-bottom property of 1.5rem, which falls in line as a multiple of our 24px baseline (1.5 * 16px = 24px).

h2 {
	font-size: 2rem; /* 32px */
	margin-bottom: 1.5rem;
}

We’ll talk about adjusting h2 proportions in the next section, but you can see from the screenshot below any subsequent p tags will now fall back in line with our vertical rhythm.

Vertical Rhythm with h Tags

Adjusting Rhythm Breaks

Once we have the vertical rhythm working  between p tags and h tags we can play with adjusting the height of the breaks.

What I mean by this is, for me, the Heading 2 in the screenshot above feels wrong. The distance between the heading 2 + the previous / next paragraphs is the same. This makes the heading feel disconnected and you’re not sure which paragraph it belongs to. I see this on a lot of websites and dislike it. However, we can change it with a bit of maths.

The simplest way to do it is add some padding above the h2. We just need to make sure it is a multiple of the baseline. Therefore we can add padding-top of 1.5rem, which is equal to our baseline of 24px (16px * 1.5 = 24px). This pushes our heading 2 away from the previous paragraph, while maintaining our rhythm.

Vertical Rhythm with h2 padding-top

We can also compress the line height. Again, we just need to make sure the baseline is always a multiple of 24px. e.g.

h2 {
	font-size: 2rem; /* 32px */
	line-height: 0.75; /* 24px / 32px */
}

You’ll see the h2 is tighter to the next paragraph in the screenshot below.

Vertical Rhythm with h2 padding-top compressed 1

Our maths has all been really clean so far, but if we want to increase our font size, it looks a lot more complicated. Again though, the maths is simple, it just looks complicated.

Here is our maths if we wanted to bump the font size of h2s up to 37px:

h2 {
	font-size: 2.3125rem;  /* 37px */
	 line-height: 1.297297297; /* We need to get to a multiple of 24px, therefore 48px/37px. Alternatively we could pull compress the line height by going down to a lower multiple: 24px/37px = .648648649 */
}

Here is a screenshot of the same vertical rhythm, but with a larger h2, as above:

Vertical Rhythm with h2 padding-top with larger h2

Hopefully this gives you a good few examples of how you can achieve vertical rhythm through rems.

Taking the time to set this up will initially feel like a chore, but will save us maintenance later. For example, if we bump up the html font-size to 110% in a subsequent media query, our vertical rhythm will stay intact, with all paddings and font-sizes increasing proportionally. I think fixed pixels appear easier initially, and maybe less complex, but if you value the rhythm and proportion of your design, which you should if you design responsively, relative units are your friends.

This entry was posted in Thoughts
  • dotnetCarpenter

    thanks for putting this together.. Probably one of the easiest to follow pieces I’ve seen on rem and vertical rhythm. just one question, why not use units when you declare line-height?

  • http://twitter.com/SparrwHawk Jay George

    Hi there, glad you liked the post. I’ll have time to do more of these one day! Pixels are absolute units so they destroy any relationship between different elements whereas if line-height is unit-less it’s like saying “2 times the base font size” or “1.4 times the base font size” or whatever the value is, and there is always a dynamic relationship there.

    Another way of putting it is that pixel units don’t “track your font-size”, as Harry Roberts puts it in his article http://csswizardry.com/2011/12/measuring-and-sizing-uis-2011-style/

  • Bart

    What about simplifying a bit and just sticking to font-size and line-height for headings. No need for margins or padding. You’ll also get the extra space above heading from the bottom margin of previous p element.