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:
- Size with px
- 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.
Conversation
This is a great method for handling font sizing, the answer to my prayers, it seems.
Thank you for posting this.
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 !
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.
This is great, I knew it existed but never bothered to look into it further thinking that the support would be abysmal.
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.
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.
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!
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. :)
I always thought it was something I was doing wrong whenever I noticed the compounding font issue with ems. Thanks - this made my day.
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.
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!
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
Oops, forgot the markup. Clickable link: https://bugzilla.mozilla.org/show_bug.cgi?id=650584
I love your joke about "if this hasn't put you to sleep yet" when dealing with REM. Hah.
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.
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.
Ah! Have been a fanatic user of em. Time to graduate to rem.
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.
In my opinion em should've worked like rem does in the first place. Thanks for this great article, very useful!
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.
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.
Regarding Josh Triplett's:
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.
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.
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?
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.
@segdeha The mobile browser CSS 'rem' Unit Support is a great list: http://ahedg.es/w/rem.html . Thanks for putting that resource together.
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.
This is really cool I think I am going to implement this on my site when I finally get around to creating it!
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.
As opposed to the “squintishly small†taking over the Web of late? :-P
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.
didn't know this. very helpful. thanks!
Very nice suggestion.
Another technique to avoid unwanted em-based cascade:
*/ }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)
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!
Servus, from Munich!
Doe's this solution also work in IE6-9.
Thank You
EdeK.
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.
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?
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
I set a base size of 10px on the body, then use percentages. Works everywhere.
Forget gradients and transforms and bling - this is the most exciting CSS3 trick I've heard of.
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 :)
Just like when I first learned of RGBA and then Chris from css-tricks showed me HSLa! Thanks Jon!
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.
Wow, this is brilliant. I am going to be implementing this ASAP on all my sites. Thanks for the head up ;)
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?
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 :(
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 ?
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.
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.
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.
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?
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.
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.
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.
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.
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
Thanks for posting - I always thought it was my crap CSS that was the cause of the em-compunding
I rather set the font-size for the body to 100%
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...