Font sizing with rem could be avoided

Jonathan Snook wrote recently about the new font-sizing unit rem. Whilst I do find it interesting and potentially useful I do think it possibly solves a problem that doesn’t actually exist…

N.B. This article isn’t a response to Jonathan’s, nor am I calling him out, he just happened to have laid some nice foundations with his article that allow me to use it as a base. It is worth noting further that Jonathan a) uses px to declare font-sizes anyway and b) does start with the base he intends to use. This article isn’t a response to his.

Jonathan uses the example:

body { font-size:62.5%; }
h1 { font-size: 2.4em; } /* =24px */
p  { font-size: 1.4em; } /* =14px */
li { font-size: 1.4em; } /* =14px? */
li li, li p /* etc */ { font-size: 1em; }

Here he sets his base font-size to 10px then creates a h1 size of 24px, <p>s and <li>s of 14px and then children of <p>s and <li>s at 1em, also 14px.

Here is a problem that developers continuously cause themselves. It’s clear here that, although he sets a body font-size of 10px, the actual base font-size is 14px. Therein lies the problem.

Creating a base font-size that you don’t actually need means you have to redefine nigh on every element to take on the size you do want—you’re creating a rule that you don’t even want and it’s causing you work…

If you want your base font-size to be 14px then set your <html> at 0.875em and you’re done. If you want a 24px <h1> then your CSS is simply h1{ font-size:1.714em; }.

The problem with 62.5%

The 62.5% trick is a common one, and does have its uses in two circumstances:

  1. You want simpler maths, for example if you are building an elastic layout (width:30em; == width:300px;)
  2. You actually want a base font-size of 10px

If you are doing neither of these then be kind to yourself and set the base you actually want.

The main reason people reset the font-size to 10px is point one; to make maths easier. If your quasi-base is 10px and you want an actual base of 12px it’s simply 1.2em. The maths is easier, we can work with units of ten more easily, but that comes at the cost of maintainability.

If you set your quasi-base at 10px and you want your body copy to be 12px, you have to style every single element that falls under ‘body copy’ individually. Hence Jonathan’s giving font-sizes to list items and paragraphs. This means you’re writing more code than you need and also leads to nasty inheritance problems; problems that rems are supposed to fix. A <p> in an <li> will be 1.2×12px, whereas it still only needs to be 12px.

If you were to just set your base at 12px in the first place (body{ font-size:0.75em; }) then:

  1. You don’t need to define every element individually; you style the exceptions rather than rewriting the rule.
  2. You don’t get crazy-annoying inheritance issues.

Being lazy is causing you more work

The main reason, I feel, behind using the 62.5% method is laziness, and that’s a good thing. Good developers are lazy. However that laziness is misguided; it’s actually causing you more work. You have to define font-sizes on all elements rather than just once and letting them inherit and you have to tackle those horrible inheritance issues when an explicitly sized element is placed inside another one.

When setting the base font-size correctly and only once the maths isn’t as nice, I’ll admit. With the 62.5% trick a font is an even ten times its em unit (2.4em = 24px, 5em = 50px and so on). With setting your base to what you actually want the chances are you will end up with a not-as-nice number. If you want your base to be 16px then 2.4em = 38.4px, 5em = 80px. It’s a little more work in your calculator app, but it’s a lot less work when it actually comes down to build.

CSS Wizardry has a base of 16px, so I just leave it at font-size:100%;. 16px is the rule, headings are the exception. As such I only need to redefine font-sizes on headings.

My maths is a little harder, my coding is a breeze…

So by all means start using rems, they seem pretty interesting, but it may just be solving a problem you don’t even have…

By Harry Roberts on Tuesday, May 31st, 2011 in Web Development. Tags: , , | 20 Comments »

+

20 Responses to ‘Font sizing with rem could be avoided’


  1. Glen Wheeler said on 31 May, 2011 at 8:41 pm

    Wow! a mistake I make quite often has been explained really well here. I always wondered why was set to 0.875em when I looked at your website code.

    A great post mate, I always come away with some great information after reading your blog posts.


  2. Made in the North said on 31 May, 2011 at 10:30 pm

    Agree with the points you make about the drawbacks of using the 62.5% method. I use a font sizing method similar to yours.

    I’m not sure that was the fundamental point Jonathan Snook was making though (at least not my interpretation). What I took away from his article is that you can avoid the “compounding” effect of font sizes specified in ems in nested elements by using the new rem unit which is relative to the root or html element.

    However, that is just my interpretation. Maybe other people have interpreted the article differently. I’ll be interested to see what others think.


  3. Matthew said on 31 May, 2011 at 11:02 pm

    I think I got so caught up with the idea that a magic 62.5% made the maths easier – I overlooked the fact that I was constantly battling with much harder maths when dealing with nested elements.

    This makes so much sense.

    Thanks!


  4. Matt Hinchliffe said on 1 June, 2011 at 11:38 am

    I’ve had a few arguments about setting font size as base 10px as it often throws maintainability out of the window – good article.

    For those too lazy to do the maths (what the parent size is / 100 * the size you want) you can always use the highly useful Em Calculator: http://riddle.pl/emcalc/


  5. simon said on 1 June, 2011 at 12:57 pm

    After reading this, I think I need to update my website but I’m too lazy – nice post.


  6. Ted Goas said on 3 June, 2011 at 3:21 pm

    *nods head* nice point about how more tedious math up front can save later CSS work to fix inheritances and maintain consistency. After reading this, I found it makes total sense for a site like this, Snook’s, and many other blogs.

    Do you think it would be tougher to employ for larger sites with more text styles? I’m thinking eComm sites, large editorials, etc.


  7. Harry Roberts said on 3 June, 2011 at 7:09 pm

    @Ted: I’m currently undertaking a massive rebuild project at work and it’s working out just fine. Easier if anything. :)


  8. Ian Harte said on 6 June, 2011 at 3:22 pm

    This cleared a lot of things up for me! Thanks keep up the good posts!


  9. thomas said on 15 June, 2011 at 3:37 pm

    I do completely support your thoughts on the 62,5% font size. But one more thing: you write that you have the choice to EITHER use nice maths with the 10px base size OR write slim css. Wouldn’t you get both benefits if you used 62,5% on the html and for example 1.2rem on the body?
    Starting from that point all px units could be easily converted to rem values if needed…
    But beeing not supported by ie6-8 this seems to be far future planning.. ;)


  10. @silvinci said on 22 June, 2011 at 10:50 am

    General Question to em: Youre expecting, that the browser’s default is set to 16px. But what if it was changed by the user to, let’s say, 40px?

    As an example, this causes your site layout here to crash. ;)


  11. Harry Roberts said on 22 June, 2011 at 10:55 am

    Well ems are relative, so this is expected behaviour. 40px is a ridiculous edge case but if it were a more reasonable value, you’d be fine—everything scales up to what the user wants.


  12. @silvinci said on 22 June, 2011 at 11:00 am

    Okay, thanks! I undestood.

    But then you should have styled your css square logo thing with an absolute size of 60px. Because this scales, too. ;)


  13. Harry Roberts said on 22 June, 2011 at 11:06 am

    Hmm. That is a good point! Thanks :)


  14. mattyk said on 22 July, 2011 at 11:37 am

    I like the idea that if you set the overall base style to your ideal body size then you don’t need to reset it on every element and therefore avoid the compounding affect.

    However, changing the base away from 16px seems to give un-roudable decimals which makes it impossible to be precise:

    Usually the maths is:

    desired px ÷ base px = amount of ems

    So usually (assuming user has a set base of 16px) if I want an 18px header I could use

    18 ÷ 16 = 1.125em

    However as soon as I change my base to 14 for example:

    18 ÷ 14 = 1.285714285 and at that point my calculator gives up.

    Browsers may be able to round that up or down but then any vertical rhythm I use gets thrown off as the screen can’t hand the sub pixels.

    I can use anything from the classic typographical scale 18,24,36 etc and dividing by 16 gives a rounded number (even if there are quite a few decimal places). Try dividing any of those by 16 and then try them by 14 and you’ll see what I mean.

    10 and 12 also seem to give roundable numbers too.
    Hope that made sense. If not or I’m just misunderstanding something let me know!


  15. mattyk said on 22 July, 2011 at 3:37 pm

    I’ve been digging a bit more on this. I think the problem is more to do with ems on the line-height and decimal places on IE8 and IE9

    IE8 and IE9 have some kind of rounding issue when not using px. See here http://www.eggheadcafe.com/software/aspnet/35883545/ie9-rounding-bug.aspx

    You can see the effect this bug has here http://www.thesheep.co.uk/examples/vertical-rhythm/ … fine in ie7 not so fine in ie8

    It seems the only way to get ie8 to work is to use pixels. Even rems didn’t work. Take this example:

    body {
    font-family:arial, sans-serif;
    line-height:1.125em;
    }

    That should be a line height of 18px right? Not in ie8. I think its to do with the amount of decimal places.

    Very frustrating but as far as I can see this only affects the line-height and not the font size so your idea is still very useful!


  16. Ray Brown said on 10 August, 2011 at 1:59 pm

    Great writeup. Thanks for bringing up your (valid) concerns about using rems as a unit of measure. I’ve written a rem() mixin for Sass that converts pixel values to rems. For instance, you could write this:

    .element {
      @include rem('padding',10px 0 2px 5px);
    }

    …and the rendered CSS would be this:

    .element {
      padding: 10px 0 2px 5px;
      padding: 1rem 0 0.2rem 0.5rem;
    }

    The mixin renders two lines of code – the first for older IE browsers and some variants of Opera, and the second for all other browsers. The converted rem values are based off of a baseline setting. So if I start a project with a baseline of 10px/62.5%, but then read this very blog post about *not* using a 10px baseline, I can change one line of code in the rem() mixin and the rest of my code scales.

    Using the example above, but with a new baseline value of 16px, the rendered output would be:

    .element {
        padding: 10px 0 2px 5px;
        padding: 0.625rem 0 0.125rem 0.3125rem;
    }

    I can finally use a baseline that makes sense, but also get the benefit of not having to crunch the numbers. This approach isn’t for everyone since it requires Sass, but it’s pretty handy and I thought you and your readers might take interest. Here’s the code: https://github.com/bitmanic/rem.

    Thanks again for the great article, Harry!


  17. Galen Gidman said on 21 October, 2011 at 11:21 pm

    You make a valid point, Harry. However, what I’ve done is use the 62.5% rule on the html tag and then set my default body font size to 1.4rem. Seems to work great for me!


  18. ldexterldesign said on 27 January, 2012 at 5:29 pm

    Thomas, Galen Gidman are correct.

    Setting =10px (base) on and then setting =13px on to act as the element all child elements (, , etc.) will inherit means I:

    a) get to use maths in a [discernible] base 10 (10px|1em|1rem), and;
    b) avoid the compounding issue Jonathan Snook identifies ( http://snook.ca/archives/html_and_css/font-size-with-rem ):

    /*
    6pt|6px / 10px = font-size:0.6rem
    7pt|7px / 10px = font-size:0.7rem
    8pt|8px / 10px = font-size:0.8rem
    9pt|9px / 10px = font-size:0.9rem
    10pt|10px / 10px = font-size:1rem (base)
    11pt|11px / 10px = font-size:1.1rem
    12pt|12px / 10px = font-size:1.2rem
    14pt|14px / 10px = font-size:1.4rem
    18pt|18px / 10px = font-size:1.8rem
    21pt|21px / 10px = font-size:2.1rem
    24pt|24px / 10px = font-size:2.4rem
    36pt|36px / 10px = font-size:3.6rem
    48pt|48px / 10px = font-size:4.8rem
    60pt|60px / 10px = font-size:6.0rem
    72pt|72px / 10px = font-size:7.2rem

    1.5|18px / 6px = line-height:3
    1.5|18px / 7px = line-height:2.571
    1.5|18px / 8px = line-height:2.25
    1.5|18px / 9px = line-height:2
    1.5|18px / 10px = line-height:1.8
    1.5|18px / 11px = line-height:1.636
    1.5|18px / 12px = line-height:1.5 (base)
    1.5|18px / 14px = line-height:1.285
    1.5|18px / 18px = line-height:1
    1.5|18px / 21px = line-height:0.857
    1.5|18px / 24px = line-height:0.75
    1.5|18px / 36px = line-height:0.5
    1.5|18px / 48px = line-height:0.375
    1.5|18px / 60px = line-height:0.3
    1.5|18px / 72px = line-height:0.25
    */

    html {
    font-size:62.5%; /* =10px */
    }

    body {
    font-family:’Helvetica Neue’, Helvetica, Calibri, Arial, sans-serif;
    font-size:1.3rem; /* =13px */
    line-height:1.5; /* =19.5px */ /* NB line-height (leading) greater than word-spacing (tracking), ensuring users read left-to-right not top-to-bottom: http://is.gd/WC6M9G, p101 */
    }

    h1 {
    font-size:3.6rem; /* =36px */
    line-height:0.5;
    margin-bottom:.5em;
    margin-top:.5em;
    }

    h2 {
    font-size:2.4rem; /* =24px */
    line-height:0.75;
    margin-bottom:.75em;
    margin-top:.75em;
    }

    h3 {
    font-size:2.1rem; /* =21px */
    line-height:0.857;
    margin-bottom:.857em;
    margin-top:.857em;
    }

    h4 {
    font-size:1.8rem; /* =18px */
    line-height:1;
    margin-bottom:1em;
    margin-top:1em;
    }

    h5 {
    font-size:1.4rem; /* =14px */
    line-height:1.125;
    margin-bottom:1.125em;
    margin-top:1.125em;
    }

    h6 {
    font-size:1.2rem; /* =12px */
    line-height:1.285;
    margin-bottom:1.285em;
    margin-top:1.285em;
    }

    Regards,


  19. ldexterldesign said on 27 January, 2012 at 5:41 pm

    Apologies – didn’t account for the HTML filter, correction:

    ‘Setting =10px (base) on html and then setting =13px on body to act as the element all child elements (unordered list, ordered list, paragraph etc.) will inherit means I:’

    Best,


  20. Corridor5 said on 3 February, 2012 at 4:48 pm

    The bulk of Jonathan’s comments were directed towards overcoming the combining effects of em space. You ended your post by saying that rem may “be solving a problem you don’t even have.” The rem unit solves an amazingly complex and frustrating problem.

    Have you have used HTML from a template library or written substantial XSLT? Transforming XML into HTML and reusing template based HTML and CSS has been an extremely difficult challenge without the rem unit.

    Highly reusable, nested HTML templates are worthless with em spaces. Text, margins, padding, and everything just gets bigger and bigger the more nested the component is in the DOM.

    Rem solves the problem of reusable/nestable HTML code.


Leave a Reply

Respond to Font sizing with rem could be avoided

Hi there, I am Harry Roberts. I am a 21 year old web developer from the UK. I Tweet and write about web standards, typography, best practices and everything in between. You should browse and search my archives and follow me on Twitter, 7,791 people do.

via Ad Packs