When it comes to setting the size of type in CSS, you have lots of options. You can apply a “keyword”, like p { font-size: small; } or a numerical value. When using a value, you need to declare a unit of measure which itself has four options. Which is best? It depends of course. Let’s take a look:
Keyword
Valid options for setting font-size in keyword are xx-small, x-small, small, medium, large, x-large, and xx-large as well as relative keywords smaller and larger.
Surprisingly enough, keyword sizing is pretty consistent across browsers and platforms. See below a test page in Opera, Firefox, IE 6, and Safari:
Note that although the they are pretty close, there are differences in where the lines break and total paragraph height.
Only when one of the relative sizing keywords are used does the “cascade” kick in and the font-size of the parent element effects the child. For example, if the parent was set to medium and the child was set to large. Only large would be used to size the child element. However, if the parent was set to medium and the child was set to larger (note, larger not just large), the child would be “sized up” to be larger than the parents font size. Change the parent, change the child, hence a “cascade”.
Keywords are a perfectly fine way to size fonts on the web. One of the more popular techniques is to set a keyword font-size on the body element, and then use relative font-sizing every where else on the page. This gives the ability to really easily size up or down the font size on the page (e.g. with JavaScript) and have the whole page move up and down in size consistently.
However, keywords don’t offer very fine-grained control of your typography, as the choices are fairly limited.
px
If you need fine-grained control, sizing fonts in pixel values (px) is an excellent choice (it’s my favorite). On a computer screen, it doesn’t get any more accurate than a single pixel. With sizing fonts in pixels, you are literally telling browsers to render the letters exactly that number of pixels in height:
Windows, Mac, aliased, anti-aliased, cross-browsers, doesn’t matter, a font set at 14px will be 14px tall. But that isn’t to say there won’t still be some variation. In a quick test below, the results were slightly more consistent than with keywords but not identical:
Due to the nature of pixel values, they do not cascade. If a parent element has an 18px pixel size and the child is 16px, the child will be 16px. However, font-sizing settings can be using in combination. For example, if the parent was set to 16px and the child was set to larger, the child would indeed come out larger than the parent. A quick test showed me this:
“Larger” bumped the 16px of the parent into 20px, a 25% increase.
Pixels have gotten a bad wrap in the past for accessibility and usability concerns. In IE 6 and below, font-sizes set in pixels cannot be resized by the user. That means that us hip young healthy designers can set type in 12px and read it on the screen just fine, but when folks a little longer in the tooth go to bump up the size so they can read it, they are unable to. This is really IE 6’s fault, not ours, but we gots what we gots and we have to deal with it.
Setting font-size in pixels is the most accurate (and I find the most satisfying) method, but do take into consideration the number of visitors still using IE 6 on your site and their accessibility needs. We are right on the bleeding edge of not needing to care about this anymore.
em
Em values are probably the most difficult values to wrap the ol’ noodle around, probably because the very concept of them is abstract and arbitrary. Here’s the scoop: 1em is equal to the current font-size of the element in question. If you haven’t set font size anywhere on the page, then it would be the browser default, which is probably 16px. So by default 1em = 16px. If you were to go and set a font-size of 20px on your body, then 1em = 20px.
Historically I think the “em” value is based on the width of the uppercase M, but don’t quote me on that.
Things start to get slightly more complicated with em’s when we start setting up more complex font sizing. Say we need a header with a larger font-size, so we set h1 { font-size: 2em; } That “2” is essentially a multiplier of the current em value. So if the current em size is 16px, that header tag is going to turn out to be 32px. That math works out cleanly, but you can imagine that it often doesn’t and rounding needs to take place.
The most popular method in working with em values is to set the font-size on the body to 62.5%. Because the default browser font-size is 16px, this makes it 10px (without hard-setting it to 10px, which wouldn’t cascade). Using 10 as a multiplier is much easier than using 16. This way, you need a font size of 18px? Use font-size: 1.8em.
So why both with all this em business when it’s just an abstraction of using pixel values anyway? Three possible reasons:
- The ARE resizeable in IE 6
- The relationship to other sizes (elastic width sites)
- Em’s cascade like a mo-fo
The first one is the big one. If you basically want to use pixels but don’t like the accessibility problems, em’s may be the ticket for you.
Em’s aren’t just for fonts, it’s a unit of measure that you can use for any other length (height, width, etc). Elastic width sites use em values for everything, which essentially makes the site “zoomable”, meaning that when you bump the font-size up everything bumps up all the way down to the width of the site. Em’s have a direct relationship to each other in this way. If you have a box that is 10em in height, and a font inside that is 1em in size, it will take up exactly 1/10 the height of that box. That exact proportional relationship makes em values a powerful web design technique.
There is one potential concern with em’s, with regards to #3. They do indeed cascade. Every em value is relative to its parents value. If you are using em’s as a straight substitution for pixel values, this can cause problems. For example, you might set both your “p” (paragraph) and “li” (list item) font-sizes to be 1.2em. Looks great for you today, but tomorrow some content is published to the site that has a paragraph inside a list item. Those two values will cascade (1.2 x 1.2) and that list item will be bigger in font-size than any of the others. No way around that, other than removing the tag.
%
Percentages are fairly obvious in how they work. That is, they work just how you think they will. If a parent has the font-size of 20px and the child has a font-size of 50%, it will come out to 10px. Just like em’s the very nature of percentage sizing is that it is relative. It also cascades in the same way, so the very problem described above of the list item and the paragraph item applies here as well.
A popular technique using percentages for font-sizing is to set a reasonable font size on the body (like “small”) and then using percentages for everything else. This allows you to swap out that keyword in a single place in order to scale the font sizing on the entire page, which makes things like a font-resizer interface feature a lot easier.
pt
The final unit of measurement that it is possible to declare font sizes in is point values (pt). Point values are only for print CSS! A point is a unit of measurement used for real-life ink-on-paper typography. 72pts = one inch. One inch = one real-life inch like-on-a-ruler. Not an inch on a screen, which is totally arbitrary based on resolution.
Just like how pixels are dead-accurate on monitors for font-sizing, point sizes are dead-accurate on paper. For the best cross-browser and cross-platform results while printing pages, set up a print stylesheet and size all fonts with point sizes.
For good measure, the reason we don’t use point sizes for screen display (other than it being absurd), is that the cross-browser results are drastically different:
Excellent post!
I use a Mac myself, and I was just wondering if you could email me a link to that IE Tester app.
Hey Andy,
Chris has a page about it here: https://css-tricks.com/ie-on-mac
I now realize it’s parallels in coherence mode.
Never mind…
I use that IE Tester program, very handy tool indeed.
I find it easier to do my ie testing from an old laptop that I have set up beside my desk. I leave windows on it and run a multiple ie program: http://tredosoft.com/Multiple_IE . This allows me to install ie 6 (and older versions) while ie 8 is installed.
Chris,
Great informative article and one that’s going to be printed out and put in my handbook.
Thanks
That’s what I should do
good read, I was surprised that the keyword values were pretty spot-on cross browser
Chris, great post. I normally use em myself but I have been caught out with the cascading feature on a couple of occasions. Thanks a lot.
Wow! Really usefeul. Thanks a lot. I’ve read other articles trying to explain this subject and this is the first time I really got a really good understanding.
Thanks,
Great roundup! My favorite part:
Ha! Same! Laughed out loud, actually. That’s going to be my answer from now on when folks ask why I use EMs.
Excellent discussion on font size issues. Bookmark worthy!!!
I have been struggling with ems for a while now, but after reading this, might switch over to percentages. Still some cascading to think about, but at least I can get the numbers so they won’t be so arbitrary as ems always seem to turn out.
Excellent, Chris. Now I understand on which reference size em’s base. All those websites that want me to change from px to em do not explaint where the base size is specified.
Good post indeed ….
And yes, it’s true: “Historically I think the “em” value is based on the width of the uppercase M, but don’t quote me on that.”
Good coverage. I like typography, and for my opinion i use pt most because they seem to be more accurate.
Don’t forget ‘ex’ which is in CSS2.
http://www.w3.org/TR/css3-values/#relative0
The ‘ex’ unit is defined by the font’s x-height. The x-height is so called because it is often equal to the height of the lowercase “x”. However, an ‘ex’ is defined even for fonts that don’t contain an “x”.
CSS3 also has some new ones:
gd the grid defined by ‘layout-grid’ described in the CSS3 Text module [CSS3TEXT]
rem the font size of the root element
vw the viewport’s width
vh the viewport’s height
vm the viewport’s height or width, whichever is smaller of the two
ch The width of the “0” (ZERO, U+0030) glyph found in the font for the font size used to render. If the “0” glyph is not found in the font, the average character width may be used.
Use http://pxtoem.com for automatic conversions
Em’s Cascade Like a Mo-Fo: Hey Chris, I think we’ve found the perfect title for the book you just announced!
Really clear explanation of the various techniques, btw — the em explanation in particular helped me understand why a design kept breaking on me a while back. Thanks as always for the excellent work.
The em-example at the end is not quite true, you can define a new rule for list-items inside paragrafs and so on to work your way around the problem.
@Chris
Actually there are a few ways, for instance, if you have set the font size of lists in ems, nested lists will have different font sizes (unless you set it to 1em). The solution is quite simple:
ul ul, ol ol {
font-size: 1em;
}
The same goes for your example:
p li {
font-size: 1em;
}
That’s the beauty of ems.
By the way, you missed a word here:
I meant
li p
notp li
of course =PIt’s true, you are right. But I disagree that’s the “beauty” of ems =). I find that to be a pain. What about nested lists that are 5 levels deep? That’s a lot of extra CSS to widdle your way back down to fight against the cascade.
Actually nested lists that are five levels deep don’t require more than:
ul ul {
font-size: 1em;
}
since this targets all lists inside another list. You can nest them as much as you want without having to change the code.
That is the beauty of CSS =)
Snookerman, thanks SOOO much for posting this comment. I never realized you can do things this way. And I fool used a separate classes for everything! NO MORE, thanks to you!
PS: By ‘never’ I mean since I started to learn CSS, which was 6 month ago.
Of course, big thanks go to Chris too, I learned so much from his articles, and this article is no exception.
Yes, you are right again, not sure what I was thinking. Unless the “nesting” isn’t just straight lists, like a paragaph inside definition list inside a unordered list inside a div, that kind of thing. But if you are doing that kind of thing you are probably well aware and can deal with it.
I do think the fact remains that it’s not quite as intuitive as setting a pixel value, in that you need to account for these (potentially unforeseen) circumstances.
That is true, ems can be a bit tricky. However, the more you use them and understand you they work, the more you are amazed of how much easier they make certain things. For example, I use the following rule:
p {
max-width: 30em;
}
This means that I will always have the same number of characters per line, regardless of the font size. If I would use pixels, I would have to recalculate and change the width of the paragraph every time I changed the font size. My design would also break if someone used a different text size. The only way to avoid that is to use ems.
Unless, of course, you want this to work in IE6, which doesn’t recognize “max-width”. . .
Isn’t that the case with everything? Heheh.. Besides, IE8 is out so I think it’s about time to drop all support for IE6 users. If you want though, there are hacks to achieve the same effect.
I hear a large portion of people still use IE 6…unfortunately. Can’t drop it just yet buddy.
Ems ems ems!
Interesting…
I shall have to ahve a proper read of this later. Another entry on my every increasing list of things to do. Ahhh well.
Daniel, I just came across this site today: http://ineedtoreadthis.com/
I haven’t tried the service yet, so I can’t speak for it nor against it, but it sounds like it might be useful for you.
I’m a fan of using YUI Fonts (and Reset), “The foundational YUI Fonts CSS file offers cross-browser typographical normalization and control.”
http://developer.yahoo.com/yui/fonts/
Alternative IE6 renderer for Firefox: https://addons.mozilla.org/en-US/firefox/addon/1419. Most of you guys probably know about it already..
The problem with IE tab for firefox is it uses the version of IE happens to be installed on your computer (in my experience with windows anyway). So if you’ve installed 7 it will only render as version 7. IETester provides for all versions up to the latest one you have installed. IEtester for IE6 gets a bit funky with really advanced layouts, but generally those aren’t the kind that have IE6 support in mind anyway.
Lovely post Chris!
I wanted to share my personal experience with em based design.
I stared using em seriously when I designed Emastic, in the beginning is little hard to switch from px to em but once you learnt how to use everything becomes more organized.
It’s not all about resize in IE6, Crome 1 and Safari 3 it is about more organized CSS. Also imagine the power that by changing one central parameter everything will change. Imagine one client saying to you “can this site be littttle more bigger or smaller” and you are saying yeah just a sec. you are going to the body( text-size) and from 1em you are writing 1.1em and all the site including the images is getting bigger. Try to built your next site with ems you will learn to love them :)
Hello,
A few things to add or to correct here.
The size of ex
Paul Hayes defined it correctly, but i want to point out that not all browsers are able to actually compute the ex size. Some browsers will just use an arbitrary 2ex=1em rule.
em, % and cascade
When used for font-size, ems and percentages are basically the same. You may use one or the other, whether you prefer percentages or decimal ratios.
When thing to keep in mind when using relative units such as % and em: don’t apply them on generic HTML elements (except html or body). Do apply them on containers, or specific elements within a container (when you know what the contents or gonna be), but beware of applying them too early in the structure.
Oh, and define a standard font-size for your body that matches the size you need for body text. If most text in your layout is 12px, then define font-size:75% or font-size:.75em for body. Then you may need to reduce the size of some text (font-size:83%, font-size:.92em…) or make titles bigger. But settling on a “convenient” 10px font-size for body, when what you actually need is text that ranges between 11px and 18px, will get troublesome as exemplified by the cascading issue you suggested.
Points are for print? Nope.
Points are not for print exclusively. Theoretically, points are for defining an absolute measure. Pixels are not absolute, since depending on your screen and chosen definition (not resolution), the resolution (pixels per inch) can go from a lot (150dpi) or very little (75dpi). Which means your pixels can be a size, or maybe half that size. Which means that text you design to be perfectly legible on your screen may look too big on your client’s screen (“please make the text smaller, ok?”) or too small to be readable on your neighbor’s screen (“hey, the website you told me about the other day? the one you said you had worked on… well i couldn’t read the text very well, it’s so small”).
Points are a solution to this issue. But browsers and operating systems need to manage those. Basically, it means:
browsers have to calculate the display size in pixels using the given value (say, 10pt) and the screen’s real resolution;
operating systems have to communicate the real current resolution, and not a default value.
I’m not sure what’s the current situation for those two criterion, in today’s browsers and OSs.
Oh, and centimeters, millimeters, inches or pica are the same story.
I found that some browsers scale differently depending on using em or % (at least as base), e.g. with one of them the font size would increase much more every step increasing it via text size option. Could be that it was IE only, don’t remember exactly.
It is IE only. It’s an IE 5-7 bug, documented here. The fix is to use just one font-size declaration in % for the html or body element. I tend to write
html {font-size:100%;}
then use EMs as i like for body and other elements. But you could use percentages only, or
body {font-size: 75%;}
for instance and then use EMs.
Though this bug has been squashed in IE8, it’s a decent reason to prefer percentages over EMs (though i personnaly tend to use EMs over percentages).
Actually this is an IE 5-7 bug, use one font-size:100% for the root html element and it’s gone.
I didn’t realize points were intended to work that way on the web. It’s definitely a smart idea. But clearly, it’s not reliable. Hopefully it will be someday, as the variance in screen resolutions and pixel sizes is getting much wider.
Great article, Chris. Thanks for posting.
I know that using px will force the font size to be exact even if the user changes their browser’s default font size or their operating system’s font size (in Windows’ Display Properties you can set it to use Normal, Large or Extra Large fonts). Are there any distinctions between keyword, % or em in respect to handling users that have bumped up (or down) their base font size?
Very nicely explained.
@3drockz
Nice post, it explained a lot of my problems with em sizes. Thanks a lot! =D
I just use px. Setting up font size dependencies is much more likely to bite you in the ass than it is to help you.
Great article! Really informative. I’ve never quite understood how em’s work, but you’ve explained it here very clearly. (just out of curiosity, what does em actually mean/stand for?)
I personally prefer to use pixels for font size – it produces the most accurate and consistent results across all browsers. I can deal with resizing not working in IE6.
After reading this bit:
I presumed it stands for the letter ‘M’ as if speaking it. I’m sure I could be wrong though.
this is a gr8 aritcle……Thank you Chris once again for a nice article….i personally prefer to use the “px”…and i am eagerly looking forward to more articles
Great article,
nice work. I’ve seen that already in w3schools and http://www.stoimen.com/blog/2009/03/04/dom-element-size-in-px-pt-em-or-percentage/ Here’s described in detail. Thanks again.
Many thanks Chris, this really clarified this evil topic of EM vs Pixel that has haunted me for a while
Another handy tool for pixel sizing is emcalc. Use it all the time, i’m lost without it.
I created a look-up table for px to em and em to em calculations which I call EmChart.
When I’m not using the 62.5%-rule, I do in fact consult that EmChart table of yours. Thanks so much creating it in the first place!
Keep up the good work buddy! I prefer use PX too.
You compose your screenshots or you use IE Tester in Mac OS? (do you emulate Win or not?)
Regards,
Gio
“Here’s the scoop: 1em is equal to the current font-size of the element in question. If you haven’t set font size anywhere on the page, then it would be the browser default, which is probably 16px. So by default 1em = 16px. If you were to go and set a font-size of 20px on your body, then 1em = 20px.”
1em is equal to whatever font size you have set in your browser settings. So your statement is mostly inaccurate.
It is by default, but if you change the font-size on your body to a different pixel size, it will change the value of 1em. Try it at home!
Hey, great article! I finally understand what em means. Thank you.
Very useful post
I use “px” for everything…
I get confused with “em” and %.
I never use “pt”
Brilliant article!
This has given me a good understanding of web typography and how to use the different mediums smoothly. I found it very easy to wrap my head around the em logic. I’ll make sure to factor these into the next layout I build.
Thanks for the awesome article man! very useful.
Great article. Thanks.
Excellent article. Like everything there just is no perfect solution. I tend to use ems because I like the additional flexibility they provide, but I often run into annoying issues with the cascading sizes. As noted in the discussion above, that’s very much the case when you have different types of elements nested inside each other, where simple CSS doesn’t fix the issue (so the li inside a p inside a div type concern).
Link to the em calculator in the comments is invaluable, never run across that before!
I translated your article into russian:
Hope you don’t mind :)
How about a link to the original? I’m not a copyright nazi but I belive in credit where credit is due. I’m going to remove the link to your site in the mean time.
Ok, I put a link to your site at the end of the article :)
How about a link to translation?
Thank you for all of the explanations.
You are correct that an em is the width of an “M”, thus the word “em”. It’s simply a typesetting term for the maximum width of any letter in a font which will be the width of “M”.
I’ve read arguments pro/con about all measurements, but decided that em’s are for me. I understand them and use them for all measurements throughout my sites. In other words, I don’t mix methods and that’s where I think many people have problems.
As far as cascading problems, I simply start every rule that has an em measurement in it with “font-size: 1em;” — that sets the size and solves any cascading problems.
You can use em’s to set the size of graphics as well so that they zoom along with text zoom — it’s something I call “Zoom-Cooperative”. Here’s an example: http://sperling.com/examples/zoom/
So, all in all, if a person can get their head around the concept of em’s, I think it will serve them well over the years and present less problems than other measurements.
Cheers,
tedd
Wel, yes. 16px is 16px. What I don’t think you realize is while 16px may be “medium” and easy to read on your computer, that’s not universally true. On my IBM laptop, for example, 16px is considerably smaller than “medium”. That’s why I think it’s better to assume that your visitors can read 100% — and any other assumption is pure conjecture.
Thanks Chris for this post. Now, I will use px font in some part
Using of px or em is bad. The character size depend of the dpi of the used display. If you have 1em = 10 px, the character height will be 10 pt on a display with 72 dpi and 5.45 pt on s screen with 132 dpi. The result is that the textes will not be readable on all hardare.
i think windows is better for web design, but we all have our favorites. thanks for this info, very useful thanks :)
Great examples, thanks. Always hard work explaining clients the use of em and stuff.
Please don’t use px to set font sizes. This is very frustrating to readers, because it varies from screen to screen depending on their resolution. If they have a screen with high DPI, your fonts will be too small to read, forcing them to set a minimum font size (which breaks your layout) or zoom in (which breaks your layout). Use sizes that stay the same from screen to screen.
What is your ideal method then? Pt is the only method that proports to solve this problem, but it falls flat in practice.
Some devices are taking it into their own hands, like the iPhone artificially bumping up sizes for readability.
Are all browser default font size 16px?
Great tutorial. Finally i understand this sizing in css.
via Email from Ken Hartley:
An “em” is a typographical measurement which goes back to letterpress days. It refers to the height of the piece of metal (or wood) that any letter in a given type font is mounted on (here I am using type font in its true meaning which is one size of one style of type). Typically the capital M was a square piece and therefore the measure became known as an “em”. Another typographical measurement is the “en” which is one-half of an em.
X-height does refer to the height of a small letter but more correctly refers to the height of the type font characters which do not have ascenders or descenders (i.e., b,d,g,p, etc.). the height is measured from the baseline to to top of the highest letter. That means that in some fonts (Garamond comes to mind) the x-height is higher than the small “x”, because of the height of the rounded letters (a, c, m, etc.).
Few designers today have handled lead type or even studied the history and origins of the typefaces they use. Many would argue it makes little difference. I think we would have fewer illegible pages.
body{font-size:10px;}
.child_percentage{ font-size:1em;border:1px solid #ccc;padding:100%;margin:100% } — as per calculation, 1em == 10px == 100%. if we apply for padding or margin. it does not work as expected
.child_em{ font-size:1em;border:1px solid #ccc;padding:1em;margin:1em; } —-font-size value is shared to padding and margin. it works perfectly fine
<div>parent</div>
<div class=”child_em”>child</div>
<div class=”child_percentage”>child</div>
Are padding and margin not calculated from parent’s font-size value in terms of percentage?
I hate to comment on such an old article, but you left off what seems (to me) the best version – “multipliers”.
Instead of “1.3em” – just “1.3”.
There seems to be an issue, that when setting line-height: 1.3em cascades, it does so at a fixed pixel value relative to the current font-size.
So, when using “1.3em” if a span or something increases that font-size, the line-height is not increased. But if you’re using just a multiplier “1.3”, then it is increased/recalculated for the “internal” span.
Kevin
Hi there,
Do you advise using the font-size:62.5% so the 1em becomes 10px size? What do you think about this? Do you recommend?
Thank god there is notepad++, where you can use regular expressions and replace everything that matches you criteria. Try it it will ease everything up. No need to replace every item on the code manually.
Chris, first of all I adore your website! So much valuable clues.
I am just starting with html5 and css3. Would you please explain to me what you’ve meant by saying that the font wouldn’t cascade? “(without hard-setting it to 10px, which wouldn’t cascade)”
Do you mean about cascading order of execution?
Like usually, great post!
If anybody is interested i have made a calculator for converting pixels to em units…
http://pixel-to-em-calculator.percovka.eu/