Font sizing using rem on Drupal 7 themes

March 7, 2012
Font sizing using rem on Drupal 7 themes

When it comes to font sizing on a website, the debate between accessibility and control rages on. The control camp prefers px font-sizes to maintain the look of the site, and the accessibility crowd prefers em to allow font scaling in the browser.

Most Drupal 7 base themes are built using ems but since the em unit is based on the parent elements font-size, dealing with the compounding of ems in nested elements can be a real pain for front-end developers. When building a list it’s likely that you’ll have an <li> nested in another <li>. If you’ve declared the <li> font-size of 1.2em then the inner <li> will be 1.2emX1.2em, and so on an so on. The math can get complicated and frustrating.

A new player in the game is the rem (and I'm not talking about the band). It functions very similarly to em, except its unit is always based on the root font-size declaration on the html element. This means that the math is simplified dramatically. I was first introduced to the rem a couple of months ago in an article by Jonathan Snook and it intrigued me enough that I used it on the most recent site we built here.

My Take on Rems

After using rems on a site build I’m a big fan. The reduced complexity makes the development of the site substantially improved. The only real downside is that font-size declarations need to be made twice due to browser incompatibility with IE8 and below.

As Snook mentions in his article, you need to declare the font-size in px first, and again in rem to accommodate IE. This allows IE9 and other browsers to use font scaling while older IE version just resort to page zooming. To me this double declaration isn’t a big deal because I would typically want to comment the em declaration with the font size in pxs anyway.  Although in Drupal 7 themes you may need to go through all the css files and the r in front of em where the theme has already used em.

Implementation Tips

Here are a few tips for anyone wanting to try using rem in your font-size declarations:

  • Define your html element with font-size as 62.5% which is 10px. The advantage of this setup is that the math is even simpler since 1 rem unit equals 10px.
  • Define your body font-size as the base font size for your site. For example 1.4rem = 14px. This declaration reduces the number of overrides you need to make to only the exceptions. Plus you can adjust the base font-size without effecting the heading sizes.
  • If you chose to define your base font-size on the <html> element instead of the body, PXtoEM.com is very helpful when making the computations necessary.
  • I continued to use em for line-heights and other spacings in order to maintain the proper spread between elements even if the font-size later changed.

The Decision

If you get frustrated by the complexity of nested ems and want to maintain the accessibility to scale fonts in the browser then I highly recommend trying rems. If you just want a pixel perfect site and force users to zoom the page instead of just the font, use pxs for your font-size declarations.

Any other Drupaler who tries or has already tried rems, let me know about your experience in the comments below.

Image: jeltovski

Comments

I also like using ems, so for

I also like using ems, so for my all projects I just use this text file (http://www.mskcc.org/sites/all/themes/mskcc_zen/) so that I can cut-n-paste the properties, with a calculation directly into my css.

Thanks, I'm going to give

Thanks, I'm going to give this a shot. Nested em's are a PITA, they always seem to happen when I'm not expecting it too.

So the font declaration for max compatability looks like (for say, a p tag):

p{
font-size: 14px;
font-size: 1.4rem;
}

I assume?

@Jake: Nice Idea! You could

@Jake: Nice Idea! You could make a text file like this using rems too.

@David: Exactly! And I really like Jake's idea of putting it all in a text file for easy copy and paste.

If you're using LESS, you can

If you're using LESS, you can also create a mixin:

.font-size(@value) {
@pixels: @value * 10;
font-size: e("@{pixels}px");
font-size: e("@{value}rem");
}

Saves typing, and you just insert the rem value like:

body {
.font-size(2);
}