CSS vertical rhythm with typography units

One of the issues frontend developers have when creating their base grid is setting up the typography. Web typography is not consistent across browsers and very hard to make pixel perfect. Here are some simple steps to ensure the vertical rhythm of the site is consistent.

1) Define a baseline unit size
We want to define a unit which matches our font-size. So for example if your default font size is 16px. Your baseline unit size could be 16px, 8px, 4px or 2px depending on the accuracy you need. For this we will use 8px and a line-height of 3 x 8px = 24px:

 * Simple Web Typography
 * base = 8px = 0.5em
 * font = 16px = 1em
 * line = 24px = 1.5em

body {
    font-family: sans-serif;
    font-size: 16px;
    line-height: 1.5em;
    margin: 0;

I've decided to leave the font-size at a pixel value to ensure compatibility cross browser and to make it clear to developers what the base size is.

2) Set any other font sizes needed first
The headings and other styles need to be set, so they are inline with the base unit size. If the font-sizes are not correct, the line-heights and margins will also be off, because they inherit from the font-size using em's:

h1 { font-size: 3.5em; } /* 16px x 3.5 = 56px */
h2 { font-size: 3em; }   /* 16px x 3   = 48px */
h3 { font-size: 2.5em; } /* 16px x 2.5 = 40px */
h4 { font-size: 2em; }   /* 16px x 2   = 32px */
h5 { font-size: 1.5em; } /* 16px x 1.5 = 24px */
h6 { font-size: 1em; }   /* 16px x 1   = 16px */

3) Reset the line-heights and margins
We also need to manually reset the line-heights and margins between type. NOTE: using em's for line-height and margin are relative to the current font size. So 1em does not equal 16px, it equals the font size. So always set the font-size first, or opt for using rem's which are relative to the base font-size:

h6 {
    font-weight: normal;
    line-height: 1em; /* relative to font size */

p {
    margin: 0 0 0.5rem 0; /* relative to base font-size */

If you don't want to use inheritance of font-sizes you can opt for rem's instead of em's. This is supported in IE9 and above:

These three techniques will get a basic vertical rhythm going in your site which is accurate enough to look great. Here is a grid showing it all put together:

If you are planning to put your type inside panels with background colours and padding. Then you will also encounter another challenge: How to make the padding even all the way around the panel with these margins.

.panel {
    margin: 0 0 1rem 0; /* add margin to our panel */
    padding: 2em; /* set even padding no matter on the content */

.panel *:last-child {
    margin-bottom: 0; /* remove the margin from the last item inside the panel */

You can see a full working example here:


No comments:

Post a Comment