Font sizing with rem

Determining a unit of measurement to size our text can be a topic of heated debate, even in this day and age. Unfortunately, there are still various pros and cons that make the various techniques less desirable. It's just a matter of which less-desirable is most desirable.

There are two main techniques that are extolled:

  1. Size with px
  2. Size with em

Let's review these two approaches before I reveal the magical third.

Sizing with px

In the early days of the web, we used pixels to size our text. It's reliable and consistent. Unfortunately, users of Internet Explorer—even in IE9—do not have the ability to change the size of the text using the browser function of increasing or decreasing font size. For those concerned about the usability of their site, this may be a big deal. Recent versions of IE include zooming, which increases the size of everything on the page—a feature that is also available in most other mainstream browsers, too. This has helped mitigate the issue to a degree.

I, personally, have been of the camp that px-based layouts provide the consistency I prefer and users have enough tools available to adjust their view that accessibility is less of a concern. But I digress. What else can we do?

Sizing with em

That whole inability to resize text in IE has been a continuing frustration. To get around that, we can use em units. Richard Rutter's article, How to size text using ems, was probably the first I read of this approach, way back in 2004. (Wow, it has been almost seven years.)

The technique modifies the base font-size on the body using a percentage. This adjusts things so that 1em equals 10px, instead of the default 16px. To set the font-size to the equivalent of 14px, set it to 1.4em.

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

The problem with em-based font sizing is that the font size compounds. A list within a list isn't 14px, it's 20px. Go another level deeper and it's 27px! These issues can be worked around by declaring any child elements to use 1em, avoiding the compounding effect.

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; }

The compounding nature of em-based font-sizing can be frustrating so what else can we do?

Sizing with rem

CSS3 introduces a few new units, including the rem unit, which stands for "root em". If this hasn't put you to sleep yet, then let's look at how rem works.

The em unit is relative to the font-size of the parent, which causes the compounding issue. The rem unit is relative to the root—or the html—element. That means that we can define a single font size on the html element and define all rem units to be a percentage of that.

html { font-size: 62.5%; } 
body { font-size: 1.4rem; } /* =14px */
h1   { font-size: 2.4rem; } /* =24px */

I'm defining a base font-size of 62.5% to have the convenience of sizing rems in a way that is similar to using px.

But what pitiful browser support do we have to worry about?

You might be surprised to find that browser support is surprisingly decent: Safari 5, Chrome, Firefox 3.6+, and even Internet Explorer 9 have support for this. The nice part is that IE9 supports resizing text when defined using rems. (Alas, poor Opera (up to 11.10, at least) hasn't implemented rem units yet.)

What do we do for browsers that don't support rem units? We can specify the fall-back using px, if you don't mind users of older versions of Internet Explorer still being unable to resize the text (well, there's still page zoom in IE7 and IE8). To do so, we specify the font-size using px units first and then define it again using rem units.

html { font-size: 62.5%; } 
body { font-size: 14px; font-size: 1.4rem; } /* =14px */
h1   { font-size: 24px; font-size: 2.4rem; } /* =24px */

And voila, we now have consistent and predictable sizing in all browsers, and resizable text in the current versions of all major browsers.

Dec 13, 2011: Opera 11.60 now supports the rem unit.

Published May 01, 2011 · Updated December 13, 2011
Categorized as HTML and CSS
Short URL: http://snook.ca/s/997

Conversation

59 Comments · RSS feed
Andrew Brinker said on May 01, 2011

This is a great method for handling font sizing, the answer to my prayers, it seems.

Thank you for posting this.

Aurélien Foutoyet said on May 01, 2011

Waoh ! Thanks for this article, I didn't know a new "magical" unit already existed.

I have to test the "rem" unit as soon as possible.
The browser support doesn't seem so poor and the fallback follows the same logic than what I already do for rgb / rgba colors, that's cool.

Thanks for sharing !

Pez Pengelly said on May 01, 2011

Fantastic!
I've been using Rutter's 62.5% font sizing technique for years and, while I love using it, the compounding em problem has been a thorn in my side ever since. The introduction of rems to css3 is a great solution and it's nice to see that most modern browsers support the feature. Definitely will implementing rem in my work.

Graham Conzett said on May 01, 2011

This is great, I knew it existed but never bothered to look into it further thinking that the support would be abysmal.

Jonathan D'Mello said on May 01, 2011

Thanks for the explanation!
This is great because it matches the way I work already. In most cases I set a base font size for body text and use multiples of that for the rest of the visual hierarchy. This is going to make all those calculations easier.

Pete said on May 01, 2011

Don't know how I missed out on the rem unit, thanks for enlightening me!

A recent solution I've used to counter the 'compound' effect leverages CSS variables available in pre-processors like less and sass:

https://github.com/peteboere/preset/raw/master/library/variables/font-sizes.css

Basically you set up a library file of CSS variables that map absolute pixel sizes to em values. For example a variable 'f16-12' would equate to 12px absolute size over 16px base font size.

Andrew Hedges said on May 01, 2011

I was interested how well this is supported on mobile devices, so I set up this page to capture support: http://ahedg.es/w/rem.html

Visit it (especially with mobile devices) please. Thanks!

Florent Verschelde said on May 01, 2011

Great article. It’s a nice overview of the techniques we can use when we want to target specific amounts of pixels for font sizes. I may start to use the technique you highlight (`html {font-size:62.5%}`, pixel sizes + corresponding font-size with rem).

But with all this focus on getting a precise pixel font-size in the end, it feels like we’re missing the point of proportional font sizes (%, em and rem). Isn’t the point of using those units to let the user agent and/or the user decide on a default font size (not always 16px)? Then we would just focus on whether the website’s design requires text that is slightly larger or smaller than usual, and on the difference between body copy (base font size) and headings, UI text, etc.

My take on this is that if we want pixels, we should use px and be done with it. The way IE handles px font sizes means that the px+rem technique can be useful, but we’re still thinking in pixels. In a time where screen resolution ranges from roughly 60 to 320 dpi (60 to 200 if you don’t count the iPhone 4’s display), SVG gets widely implemented and CSS decoration properties allows us to reduce or eliminate decorative background images, we may need to change or mindset and work on or px addiction. :)

Stepher said on May 01, 2011

I always thought it was something I was doing wrong whenever I noticed the compounding font issue with ems. Thanks - this made my day.

Chris Marsh said on May 01, 2011

Excellent post - it's a great new feature! Good to see it already has decent support, and I'm surprised it isn't better known.

Chris Jacob said on May 01, 2011

WOAH.

REM's look like a brilliant "future web development" browser feature. The fact that you can fall back to PX and start using this RIGHT NOW is beyond awesome.

I'm going to investigate using it in an Adaptive Web Design / Template I'm working on...

How exciting! Thanks for the tip!

Waldir Pimenta said on May 01, 2011

Thanks a lot! This might just allow me to neatly solve (as opposed to hack a workaround for) an issue I had a few days ago that led me to discover a bug in Firefox/Linux in that the input element doesn't actually inherit the parent's font-size: https://bugzilla.mozilla.org/show_bug.cgi?id=650584

Waldir Pimenta said on May 01, 2011

Oops, forgot the markup. Clickable link: https://bugzilla.mozilla.org/show_bug.cgi?id=650584

Michael Whalen said on May 01, 2011

I love your joke about "if this hasn't put you to sleep yet" when dealing with REM. Hah.

Josh Triplett said on May 01, 2011

Please don't set the top-level font size using percentage; effectively, that says "take whatever the user wanted and make it smaller". Instead, if you really want to set a base top-level font size, set it in pt.

Even better, don't set the base font size at all; respect the user's settings. Just size elements such as headings proportionally larger.

Kien N said on May 01, 2011

Awesome. I remember hearing about rem a few years back (2007? - Firefox 1.5?) but then it had zero browser support and was only something to be considered in the really far future. And sadly, it still won't be safe to implement rem in at less a couple of years, I think. IE8 and below still have a too large piece of the market share.

Brajeshwar said on May 01, 2011

Ah! Have been a fanatic user of em. Time to graduate to rem.

Keith said on May 02, 2011

This is SUPERB. I was ranting about this on twitter about 2 weeks ago, although in my opinion you should be able to set the root point...

To Josh Triplett above:

The percentage top-level in the 62.5% "hack" is almost always used with an em value greater than 1 for base text; so really you're not saying that at all.

Linda said on May 02, 2011

In my opinion em should've worked like rem does in the first place. Thanks for this great article, very useful!

Martijn said on May 02, 2011

This means that we can't use it until, say, 2015, because almost all website still need to support IE8 and to a degree IE7.

Thomas Scholz said on May 02, 2011

Never size the base font down to 62.5%. If the desired result is below the user’s minimum font size, the real results are unpredictable and the rendering becomes slow. This technique has never worked really good. It’s history like Netscape 4.

Ryan Cannon said on May 02, 2011

Regarding Josh Triplett's:

Please don't set the top-level font size using percentage; effectively, that says "take whatever the user wanted and make it smaller".

Default font size isn't a function of user preferences; it's a function of history. Browsers started using 16px as the default size years ago, and every browser since has had to use this garishly-large size for compatibility, and probably will for the foreseeable future. There's nothing wrong with managing the size for body appropriately for modern browsers. Don't forget, the Web looked a lot different when 16px was chosen as the default.

Thierry Koblentz said on May 02, 2011

Hi Jonathan,

fwiw, I never liked that "font-size:62.5%;" technique on body. Imho, it leads to too many issues depending on user settings.

I wonder if rem solves this problem though.

Thanks for writing about this.

Gerald Fullam said on May 02, 2011

Why use the 62.5% rule at all? Why not declare 10px on the body or html element and use ems everywhere else? The 62.5% rule relies on a user's browser default being set to 16px — most are — but some users modify this setting.

If your goal is to eliminate font sizing problems, then why implement a technique that causes font sizing problems for a different set of users?

Will declaring a fixed font-size of 10px in the body or html element prevent IE/Win users from resizing other elements based on ems?

Lucian said on May 02, 2011

I always used 62.5% on body combined with em method, however I don't see too many benefits in using the rem.

First of all, if you want to support IE7/8 you need to always add the fall-back size in px. From my experience, when using ems, the only reset you need to is for nested lists.
Trust me, it is easier to add few lines of code than adding both px and rem sizes for all elements.

For websites that need only IE9+ support I think is a great new function but it is not ready for deployment yet.

Robert Visser said on May 02, 2011

@segdeha The mobile browser CSS 'rem' Unit Support is a great list: http://ahedg.es/w/rem.html . Thanks for putting that resource together.

Oliver said on May 02, 2011

Yes, BUT it brings back the "not resizing" problem in IE6, so at this moment it is not the holy grail. It only makes it easier for the designer but brings no improvement for the user.

tom said on May 02, 2011

This is really cool I think I am going to implement this on my site when I finally get around to creating it!

seutje said on May 03, 2011

I'm with mister Triplett on this one. Setting the root Font size in % only works the way u want if the user hasn't touched his browser settings, if his font size is set to 14, ur effectively making things a lot smaller than u expected. So this assumption isn't only bold, but sorta rude as well. Like if someone would order a large sub and he'd get a small one instead...
I Usually define my root size in px and add controls if the project requires font scaling. Agreed, it's equally rude, but more accurate.

Aankhen said on May 03, 2011

Browsers started using 16px as the default size years ago, and every browser since has had to use this garishly-large size for compatibility, and probably will for the foreseeable future.

As opposed to the “squintishly small” taking over the Web of late? :-P

Pedro Duarte said on May 03, 2011

Yeah I like the idea a lot actually, just a shame it's not supported by all browers.
I don't like the thoguht of having to specify the font size in px too for older browsers, so I'd stick with em until all browsers support rem, which is in probably 20 years time.

Nathan B said on May 03, 2011

didn't know this. very helpful. thanks!

Corey Innis said on May 03, 2011

Very nice suggestion.

Another technique to avoid unwanted em-based cascade:

  /* use child combinators (supported from IE 7) */
  div#context_element > ul > li {
    font-size : 1.25em; /* will not compound on nested
  • */ }
  • Note that I also tend to use px (12 is a nice baseline and the em math is still pretty simple... round at the 1000th place) and "reset" at various key points (e.g., forms)

    doug_eike said on May 03, 2011

    Great explanation! I'm using WordPress and am learning css. Right now, I'm overriding the default for the <h2> tag with a 1.2em. The compounding issue is intriguing. Thanks!

    Ede Kowalski said on May 03, 2011

    Servus, from Munich!
    Doe's this solution also work in IE6-9.
    Thank You
    EdeK.

    Chris Jacob said on May 03, 2011

    I would love to know what people think of this demo I've whipped up...

    ------------------------------------------
    ROOT EM! Using CSS3 "rem" Units for "Elastic Pixels"
    ------------------------------------------
    JSBin Preview: http://jsbin.com/acide4/8
    JSBin Code: http://jsbin.com/acide4/8/edit

    @_chrisjacob if you want to discuss on twitter.

    Kinescive said on May 03, 2011

    Hey, tell me please, I am now in Greece, and my parents are in Moscow how to to pay them anything so we could talk cheap? I found just such a story, maybe someone has used a similar service, or heard of him? Tell me please whether this actually real?

    Gaurav Mishra said on May 03, 2011

    Hello J. Snook
    REM seems very a logical visual unit. And If not put to sleep... may help a designer to distinguishably add the pixel diet to font, based on a hierarchy.
    Thanks for sharing!

    Namaste from India
    Gaurav M

    Peter Gasston said on May 04, 2011

    I set a base size of 10px on the body, then use percentages. Works everywhere.

    Amy Hendrix said on May 04, 2011

    Forget gradients and transforms and bling - this is the most exciting CSS3 trick I've heard of.

    Michael Fields said on May 04, 2011

    This is amazing! Thanks for writing it up. Definitely need to start using rem over em for my layouts. Everytime I think about using them, I hear "It's the end of the world as we know it ..." in my head. Added bonus :)

    Montana Flynn said on May 04, 2011

    Just like when I first learned of RGBA and then Chris from css-tricks showed me HSLa! Thanks Jon!

    Bryan Paterson said on May 04, 2011

    I'm curious as to why this is useful. The reason that people started using em based font-size was to provide IE with the ability to zoom in and out correctly. By falling back to px for IE 7/8, this goes right back to the same issues people had with px based font-size.

    That being said, you could use em font-sizes in a pre-IE9 only stylesheet (included using IE conditional comments) to have the best of all worlds.

    Blake Embrey said on May 04, 2011

    Wow, this is brilliant. I am going to be implementing this ASAP on all my sites. Thanks for the head up ;)

    Bruno De Barros said on May 04, 2011

    Hold on a minute. You said the con of px was that most IE users couldn't resize it properly. Then you talk about rem, which can't even be understood by most IE users. Isn't that even worse? The point of em was to fix sizing in older IE versions. rem doesn't solve that, so how is it any better than px?

    Rhys said on May 04, 2011

    Ive been a big fan of em for years but have to say Ive been thinking of using px instead these days perhaps because Im more interested with mobile devices and figgured most modern browsers default to zoom rather than Text Zoom. I had assumed IE9 would be cool with px by now :(

    Paul said on May 05, 2011

    Hi Snook

    Great post here, though, i got on question, i hope u ( or somebody else who knows the subject ) don't mind answering this one simple question.

    Concerning the font size aspect of the web.

    Right now it seems to me that em has no benefit at all, since all the modern browsers now support full page zoom ( Ctrl + - 0 )

    So what exactly is the point of using em or rem instead of px ?

    Matt Hinchliffe said on May 05, 2011

    I can certainly see the uses in new rem unit for code maintainability; for instance when using separate stylesheets or if the font sizes are all bumped up or down at a later date. However I hate finding the body set to 10px, it's lazy and at some point you will end up with content without any styles affecting it, thus being unreadable.

    Em calculations take just a second (value is pixels you have / 100 * value you want) or use a service such as Em Calculator.

    Richard said on May 05, 2011

    Think I'll stick with px.

    The one partially sighted person who also happens to be on IE so can't resize is just going to have to lump it.

    Nate Johnson said on May 06, 2011

    Love this post. I really haven't understood em completely, but I now understand that AND rem. This was to the point, and extremely informative. Well done.

    dougwig said on May 06, 2011

    Thanks for the post, didn't know about rem sizing.

    If the same browsers that support rem resizing also support px resizing, I have to ask... why not just use px?

    Andrew said on May 08, 2011

    Thanks for posting this. I had previously "given up" and just used px for everything, but now I can use rem and fall back on px! I will be using this immediately.

    Sudip said on May 09, 2011

    It depends upon the author what he would as an unit for font size. Many prefer using %, some use px, and em too. I think with proper structure as well as usage, all of those work fine.But since rem is being introduced in CSS3, we have another option in our bag now. That is significant. More option brings more flexibility, for sure. As far as CSS2.1 is concerned, CSS Values is a good tutorial to know about units used.

    Stuart W. said on May 11, 2011

    I use ems because I want IE users to be able to resize, otherwise I'd use pixels and not have to do all the inheritance calculations, rems sound great but aren't supported in the browsers I'm solving for so I don't see a reason to use.

    phobia said on May 11, 2011

    I definitely look forward to using rem as font unit one day, it's exactly what we need.

    However, isn't it a bad idea to have px as fallback? One of the reasons to use relative units in the first place is that older IE can't scale text defined in px.

    Marcello said on May 12, 2011

    Absolutely amazing! The difficulties in controlling dependencies is the main reason I've never been a fan of ems. This should solve my problem! :D

    Ian Hallworth said on May 17, 2011

    Thanks for posting - I always thought it was my crap CSS that was the cause of the em-compunding

    Jo said on May 21, 2011

    I rather set the font-size for the body to 100%

    Nikita said on May 26, 2011

    Jonathan, thank you so much for this article and this delicious site! You site's design elevates my mood, and I don't know really why...

    Sorry, comments are closed for this post. If you have any further questions or comments, feel free to send them to me directly.