CSS Font-Sizing: a Definitive Guide

CSS font sizingFont sizing in CSS sounds as though it should be easy. Until you try it. Many developers use the force; they tinker with the font-size property until it looks right only to find it’s different in another browser. A little understanding can go a long way…

The font-size Property

The font-size property can be set for any HTML tag (even if it would not normally contain textual content like br). It can be assigned a variety of absolute, relative, or length size parameters.

An element will inherit the font-size of its parent unless you override it. This is especially important when you specify relative sizes.

Absolute Font Sizing Keywords

Several absolute font-sizing keywords are available. The font size is determined from a browser preset and the element will not inherit its parent’s size.

  • font-size: xx-small;
  • font-size: x-small;
  • font-size: small;
  • font-size: medium;
  • font-size: large;
  • font-size: x-large;
  • font-size: xx-large;

Although most browsers support these keywords, the exact sizes will differ. They are a fairly crude method of font sizing and are generally avoided by most developers.

Relative Font Sizing Keywords

Two relative font-sizing keywords are available. The font is sized according to its parent element:

  • font-size: smaller;
  • font-size: larger;

For example, if the parent has a font size of ‘medium’, a value of ‘larger’ will set the element to ‘large’. Other font units are normally altered by a factor of around 1.2 but, again, there is no standard and browser results will differ.

Absolute Lengths

The font-size property can be assigned an absolute length:

  • mm: millimeters, e.g. 10mm.
  • cm: centimeters, e.g. 1cm ( = 10mm).
  • in: inches, e.g. 0.39in ( ~= 10mm).
  • pt: point, where 1pt is generally assumed to be 1/72 inch e.g. 12pt.
  • pc: pica, where 1pc is 12pt
  • px: pixel, e.g. 14px.

In general, there are issues with all these measurement units. Millimeters, centimeters and inches are inaccurate for a screen-based medium. Points and picas are unreliable since systems can use different dpi settings. Pixel appears to be the most suitable, but it can lead to accessibility issues because the text cannot be resized in IE.

Relative Lengths

The font-size property can be assigned a unit that it relative to its parent’s font size:

  • em: 1em is equivalent to the current font size, so 2em is twice as large.
  • %: 100% is equivalent to the current font size, so 200% is twice as large.
  • ex: 1ex is equivalent to the height of the letter ‘x’ in the current font.

Few developers use ‘ex’, but it can be useful in some situations where you need fine-grained font sizes, e.g. 1ex rather than 0.525em.

Percentage and ‘em’ sizes are equivalent, e.g. 50% = 0.5em, 100% = 1em, 120% = 1.2em, etc. Some browsers exhibit subtle differences but it’s rarely a major problem. If you want to save every byte, you could choose the shortest definition, i.e. 50% is shorter than 0.5em and 1em is shorter than 100%.

Text Sizing and Page Zooming

This is where additional complexity creeps in. Most browsers allow the user to:

  1. increase or decrease the base text size (image dimensions are not changed)
  2. zoom the page in or out so all the text and graphics change accordingly, or
  3. allow both text sizing and page zooming.

Just to complicate matters further, Internet Explorer does not allow text resizing on elements which have a font size defined in pixels (px).

If you’re a designer moving to the web from a print background, it’s disconcerting to give the user that much power. Your design could be ruined by a user zooming in 200% but reducing the text size to 50%. And — no — there is nothing you can do to prevent it. Nor should you.

CSS Font Sizing Recommendations

The general consensus is that ‘em’ or ‘%’ is the best solution in most situations. Fonts can be finely scaled relative to each other and browser text sizing is supported. I would also recommend using a percentage font-size on the body tag; it results in better text-sizing in some older browsers.

There are a couple of other recommendations I would suggest when you’re developing a site:

  1. reset the font size and page zoom to their default values in all your browsers before testing (it’s caught me out a few times!)
  2. try reasonable combinations of text sizing and page zooming in a variety of browsers to ensure the text remains readable.

Has font sizing ever caused you problems? Do you have any other tips?

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://www.dan-schulz.com Dan Schulz

    I normally start by resettin the default font size on the body selector to 85% and the leading (line height) to 1.5

    I’ve found this works best for people who change their DPI settings from the defaults (96 .dpi in Windows, 75 .dpi in Linux) to a larger setting (especially those running at 1600×1200), such as 120/100 .dpi (Win/Linux, respectively — that reads as 120 .dpi in Windows, or 100 .dpi in Linux).

  • http://www.optimalworks.net/ Craig Buckler

    @Dan
    I agree: an 85% body font size gives a fairly ‘normal’, readable text which is consistent across browsers. Thanks for the tip.

  • Anonymous

    The text can be resized in IE if you use px as an absolute size.

  • http://www.optimalworks.net/ Craig Buckler

    The text can be resized in IE if you use px as an absolute size.

    The page can be zoomed, but the text can not be resized (View > Text Size). Even IE8 does not support px text resizing.

  • http://www.dan-schulz.com Dan Schulz

    Craig’s right (as usual). IE cannot resize pixels. Though given the way all browsers tend to handle pixels, I rarely use them except for sizing images and form controls (like setting the height on input elements for instance).

  • http://www.optimalworks.net/ Craig Buckler

    @Dan
    Going a little off-topic here, but are there any benefits to sizing input heights using px? Normally, I set the input’s font size in em and let the browser worry about the actual height of the box. I often set the padding in pixels, though.

  • http://www.dan-schulz.com Dan Schulz

    Well, the way I code forms is rather weird, and it’s the only way I’ve been able to maintain a consistent height between text inputs and submit buttons (search forms are a great example of this).

    Then again, the spec doesn’t tell the browsers how to actually render the forms (frankly Opera’s the only one to get them right — treat them all as inline-block and be done with it; too bad Gecko browsers still trip over their own feet with inline-block depending on the version; Firefox finally got around to fixing it, but I can’t say the same for the forks).

  • Anonymous

    About font-size, browser have to calculate % to computed value before,
    but do not require to calculate em to computed value.
    I am not sure that em (or ex) will be calculated to px for used value or not.
    But I think use em better than % for performance.

    Reference
    http://www.w3.org/TR/CSS21/cascade.html#computed-value
    http://www.w3.org/TR/CSS21/fonts.html#font-size-props

  • Gaiz

    About font-size, browser have to calculate % to computed value before,
    but do not require to calculate em to computed value.
    I am not sure that em (or ex) will be calculated to px for used value or not.
    But I think use em better than % for performance.

    Reference
    http://www.w3.org/TR/CSS21/cascade.html#computed-value
    http://www.w3.org/TR/CSS21/fonts.html#font-size-props

  • http://www.cemerson.co.uk Stormrider

    Am I the only one that thinks IE has it right when it doesn’t resize px sizes? In fact, since it is listed under your ‘Absolute Lengths’ section, that is expected behaviour – RELATIVE units change size with text zoom, ABSOLUTE is absolute, surely? None of the measurements in that section should resize with changing text sizes (and in fact that is echoed in the spec).

    There is an error in this article though in that px is actually defined by the w3c as a relative measurement, but this means relative to the device it is being viewed on, not relative to the browser’s base font size.

    From the specs:

    Pixel units are relative to the resolution of the viewing device, i.e., most often a computer display. If the pixel density of the output device is very different from that of a typical computer display, the user agent should rescale pixel values. It is recommended that the pixel unit refer to the whole number of device pixels that best approximates the reference pixel. It is recommended that the reference pixel be the visual angle of one pixel on a device with a pixel density of 96dpi and a distance from the reader of an arm’s length. For a nominal arm’s length of 28 inches, the visual angle is therefore about 0.0213 degrees.

    For reading at arm’s length, 1px thus corresponds to about 0.26 mm (1/96 inch). When printed on a laser printer, meant for reading at a little less than arm’s length (55 cm, 21 inches), 1px is about 0.20 mm. On a 300 dots-per-inch (dpi) printer, that may be rounded up to 3 dots (0.25 mm); on a 600 dpi printer, it can be rounded to 5 dots.

    The two images below illustrate the effect of viewing distance on the size of a pixel and the effect of a device’s resolution. In the first image, a reading distance of 71 cm (28 inch) results in a px of 0.26 mm, while a reading distance of 3.5 m (12 feet) requires a px of 1.3 mm.

    From what I understand in this, px values SHOULDN’T resize when changing text size, because the size of a pixel on your display doesn’t change. IE has it right here, all the other browsers have it wrong.

  • http://www.optimalworks.net/ Craig Buckler

    @Dan
    Mmm – that’s a good point. Search forms with same-height input and submits can be a nightmare. I often resort to graphic solutions, but it normally requires a lot of tweaking to get right.

    Interesting tip, though — thanks. I’ll definitely try that at some point.

  • http://www.optimalworks.net/ Craig Buckler

    @Stormrider
    Interesting points. IE does not resize any of the absolute length units (mm, cm, pt, etc.) so at least it’s consistent.

    Whether it’s right or wrong, the distinction between text sizing and page zooming is a little blurred and can confuse (see above). I always liked text resizing because it didn’t make images and adverts bigger, but page zooming is becoming the norm.

    Personally, I think the user should be permitted to resize the page/text as they want. Using em or % allows that in all browsers, including IE.

  • http://www.benwarren.co.uk benji

    Page zooming is by far and away a better idea. When you wants your text bigger you except things to get bigger. Not for the text start breaking out of boxes etc.

  • http://www.deanclatworthy.com Dean C

    I use 62.5% as my base. Depends on what you want your base font size to be of course :)

  • http://www.optimalworks.net/ Craig Buckler

    @benji
    I agree that page zooming is more logical, but most sites use fixed width dimensions, so zooming often makes the page width larger than viewport.

    It’s possible to create a fluid/elastic designs where elements contract or expand depending on the text size. Image sizes remain the same and the text flows around them. Unfortunately, it’s becoming a forgotten art.

  • aljuk

    “Benji says: Page zooming is by far and away a better idea. When you wants your text bigger you except things to get bigger. Not for the text start breaking out of boxes etc.”

    I totally agree. All modern browsers now support page zoom. After several years of setting base to 62.5% and using ems on top of that, I’ve gone back to using px.

  • Stevie D

    @Stormrider:

    Am I the only one that thinks IE has it right when it doesn’t resize px sizes?

    I’m with you on that. I despise IE as much the next man, but I agree that, if you specify a font size in pixels, the browser should respect that – and even more so now that all current browsers support page zooming as well as text resizing.

  • Stevie D

    It might be worth the people who write the stylesheets for Sitepoint reading this article ;-)

    At the moment, any text in <blockquote> tags is much larger than the rest of the comment text … looks a right mess!

    (That’s in IE6 (not out of choice, my work PC is locked down!))

  • Matt Wilcox

    Pixels are relative, not absolute. A CSS pixel is not the same thing as a physical pixel.

    IE’s behaviour of not resizing pixel based measures is wrong on these grounds.

  • LFA

    I normally start by resettin the default font size on the body selector to 85% and the leading (line height) to 1.5

    85% of what? Doesn’t this require an absolute value somewhere?

  • Jeremy

    I always set the html tag to font-size: 100%; to fix the “old browser” problem and then the body tag to font-size: 0.8125em; from there I scale up or down for the elements in my design.

  • http://percept.be Percept

    I always go with %-based font-sizes.
    The allow the user great flexibility and it scales much better then em’s.
    When you resize the text, %-based font-sizes don’t scale as much as em-based which is why I prefer %.

    The only thing you have to watch out for is when using text in elements which are set to overflow: hidden. It doesn’t usually pose a problem but it still good to think about.

  • jasonkarns

    @Stormrider, @Craig Buckler, @Stevie D

    Actually, px are Relative units as defined by the CSS spec

    The difference with px is that they are not relative to other elements or other font-sizes. Px are relative to the user’s viewing device. As defined by the spec, a px should be based off of the dpi (standard was 90dpi for CSS 1 and is now 96 dpi for CSS 2.1) of the device and the standard reading distance of the user (usually arms length). With these rules in mind, a px is roughly 1/96 inch.

  • jasonkarns

    @Dan, @Craig I find 85% an odd number. By default, the text size for most browsers is 16px. Setting the base to 85% (13.6 px) of that could generate rounding differences between browsers. For this reason I set my base font to 87.5% which is 14px exactly.

    @LFA Setting the base font size (usually with body {font-size:87.5%;}) will size the page’s font based on the browser’s default, which in every case I’ve tested is 14px. Additionally, setting the base using a % value rather than em for some reason, has the added benefit of reducing the scale in IE. In other words, % and em-based font-sizes in IE have very large ‘jumps’ between the user-specified text-size (medium->large, etc). Setting the base size in % decreases this jump to a much saner amount.

    An article that should be required reading for font-sizing is over at A List Apart: http://www.alistapart.com/articles/howtosizetextincss/

  • VodkaFish

    I use YUI fonts:
    http://developer.yahoo.com/yui/fonts/

    Helps me get a very standardized base to work with.

  • http://www.fosterstudios.com fstudios

    html {font-size: 100%;}
    body {font-size: 0.8125em;}

    Then I size my elements from there.

  • http://www.clearwind.nl peach

    I think Stormrider makes a good point about ie not resizing absolultely sized text. Never thought about it that way but it would be better!
    You can have both resizeable text and big absolutely sized headings in internet explorer.

    must be the first time I have something positive to say about ie.

  • dmwalk

    The font-size for this article is set to small which Craig says is “generally avoided by most developers.” Why does SitePoint take this approach?

  • http://aloestudios.com AnalogPanda

    Relative font sizes (via % and/or em) are definitely the most flexible approach, but dealing with the math can be a pain! I created a lookup table for px to ems. But it’s also useful for calculating ‘em to em’ and other properties like line-height and margin.

  • Stevie D

    @dmwalk:

    The font-size for this article is set to small which Craig says is “generally avoided by most developers.” Why does SitePoint take this approach?

    Because a lot of designers either don’t know about the sizing keywords, or don’t like the dangerously unpredictable nature of them (ie, the font could [shock, horror!] be 1px larger in one browser than another). Worrying about the exact and precise font size is unproductive and unhealthy, and it’s no great surprise or concern that SitePoint, being enlightened as it is, goes for a simpler solution.

  • neovive

    I would also assume that most people who want to increase the font size would use the zoom functionality vs incresing the text size, which creates some rendering problems. It’s very easy to ctrl+ or ctrl-, thus using pixels is probably ok in most situations. I usually define certain elements in em’s, but find myself switching back to pixels, since em’s are more difficult to work with.

  • http://www.optimalworks.net/ Craig Buckler

    @jasonkarns
    Font sizes will be rounded and, even then, rendering will depend on the OS, browser, and the font itself. Using 85% will be identical to 87.5% in most cases. It may cause differences when you scale up or down by a significant amount but, in general, I rarely find it necessary to calculate exact font sizes.

  • http://www.cemerson.co.uk Stormrider

    Matt Wilcox: px is relative, but NOT relative to a base font size like % or em is, relative to the viewing device and resolution instead. Relative to the size of 1 pixel on the screen, although not necessarily the same size as it.

    jasonkarns: Yup, this is what I said.

  • base font as medium, small

    I usually, set my base font as:

    body {
    font-size: small;
    }

    Is percentages recommended instead of this? I’ve always found this to work good. I was wondering what others thought about this?

  • Anonymous

    There are tens of thousands of middle-aged readers who would be only too happy to pistol-whip any designer who reduces the base font size.

  • Becca

    Does anyone else experience a 3-4 pixel font-size difference between browsers? That is why I don’t use ems. I stick to pixels so I know my site will be consistent across browsers. Too many picky clients telling me they must all look the same. Although I would like to use ems all the time, because of this I only use them when it is explicitly outlined in the requirements the the text size be resizable. Sad, but true.

  • http://www.cemerson.co.uk Stormrider

    @Becca – That’s a case of client education. The web is not the same as print, there are differences between browsers, and there should be. You should explain the accessibility implications (and therefore legal implications) when you use non resizable measures. I’m sure it’s something that can be easily explained, especially when you bring accessibility laws into it!

  • 9swords

    I am using pixel units as a measurement for font sizes, and haven’t noticed any readability issues in IE, even at different resolutions. I don’t need my pages printed and do not use a print style sheet. If i did, i would use whatever measurement is more compatible with printing. A css reset with font-size: normal; can also be useful. I should probably go through my style sheets and switch over to em’s for best practices and accessibility. Thank you for this interesting and informative post.

  • Gaiz

    In my opinion, I strongly recommend to use “px”
    because
    1. If you would like to add any buttons to increase/decrease font and change it by JavaScript.
    If you use “em” in CSS, Firefox, Opera, Safari and Google Chrome will return computed value in “px”,
    but IE will return “em”
    Let try the code below to get font size:-

    var content = document.getElementById(‘content’);
    var fontSize;
    if (document.defaultView) {
       fontSize = document.defaultView.getComputedStyle(content, null).fontSize;
    } else {
       fontSize = content.currentStyle.fontSize;
    }
    alert(fontSize);

    2. Zoom is browser feature, I tested with IE8 (8.0.6001.18813), it can zoom already
    3. Performance, Specified value in unit “em”, “ex”, “%”, … have to calculate to “px” when it’s changed to computed value

  • {RainmakeR}

    Strange I haven’t seen any mention of the so-called 76% rule here yet? I’m not sure if it even still applies, but back in the early days of relative font sizes, the general consensus seemed to be that the following rule:


    body
    {
    font-size: 76%;
    }

    …would set the base font size to be the equivalent of whatever is considered “normal”; I think it works out at about 10pt for sub-elements with no further relative sizing. I don’t know where the 76% came from – personally I use 75% because I like a nice rounded percentage and I don’t think a difference of 1% is going to destroy the universe as we know it.

  • {RainmakeR}

    Ah here we go, I believe the 76% thing stemmed from here:

    http://www.thenoodleincident.com/tutorials/box_lesson/font/index.html

  • http://www.optimalworks.net/ Craig Buckler

    @Becca
    Most browsers are fairly consistent. Are you using a DOCTYPE? It’s possible that slipping into quirks mode might affect some IE font sizes.

  • http://www.cemerson.co.uk Stormrider

    @{RainmakeR} That might work for the default sizes in browsers, but a lot of people change them. You should design a site to accommodate different sized text at the end of the day, as the user can change the size to whatever they want.

  • http://www.clearwind.nl peach

    Anonymous @ August 21st, 2009 at 5:52 am;

    maybe they should whip the newspaper and magazine designers too…

  • martin

    only monkeys and old designers in the field use em’s and not px, and because they do all the extra work for 0.1 percent of all users to get the web site as good as for 99.9 percent, they always bitch about the designers who use px.

    all browsers have zoom by default. almost every new significant portal is FIXED. almost all new facelifts of old designs switch to fixed. and there is nearly ZERO chance that px can be viewed badly in browsers and devices. I even can say that using EM’s can make a lot of problems to preview web site as it was created to preview in some browsers / devices than pixel based font settings.

    we live in 2009 ant NOT 2002 anymore – liquid sites and em’s are dead, so old designers shut up and just stop bitching because you failed. why? because i design from 1998 and i’m using static designs with pixel fonts 11 years in a row and didnt hear ANY complaints about my created web sites being wrongly viewed because of that! and all these 11 years my collegues were teasing me about “non-professional” attitude for ignoring liquid and em’s. you know where are they now? DESIGNING STATIC PORTALS AND USING PIXELS. because i was right.

  • josh sherman

    martin, could you link me your website?

  • http://chelseacreekstudio.com/ davidlaakso

    CSS Font-Sizing: a Definitive Guide? You’ve got to be kidding. Nothing personal, Craig, but face it– you ain’t ain’t got a clue.

  • http://www.dan-schulz.com Dan Schulz

    @LFA and @jasonkarns – the 85% is set to whatever the user has set as his or her browser’s default. While many people don’t change that setting, some do. And others still will leave the font size alone while altering the display settings (DPI).

    Remember, there is no “default size” that equates to a fixed value – just as 62.5% != 10px.

  • mrmazda

    Sizing text in px, pt, pc, mm, cm or in completely disregards whatever size the user finds most appropriate, as reflected in his browser’s default size setting(s). Completely disregarding user preferences is rude.

    Sizing body or your main content to anything other than 100%, medium or 1em is also rude, as it is saying that no matter what default size the user has selected, he chose too big, and you somehow know better than he does what’s best for him and are imposing (an arbitrarily) smaller size. This is also rude.

    Browsers are user agents, not web designer agents. Their minimum text size, text zoom, and page zoom are all mechanisms for defending against rude designers. Absent the offensive results from designers who disregard preferences entirely or shrink text from users’ preferences, these defenses aren’t needed. Users shouldn’t need them, and don’t need them, when you politely design to accept that their choices are the right choices for their environments.

    User environments vary widely, from below 70ppi to over 140ppi. Eyesight varies widely too, as does viewing distance, ambient lighting, and display brightness & contrast, all of which affect what sizes work best. You can only know what’s best by being there, using their eyes. Since that’s not remotely practical, next best is letting them choose how to personalize their personal computers, blackberries or whatever else they surf with. Your designs can, and should, be polite, by accommodating those choices, whatever they happen to be.

    If you aren’t sizing in em or %, leaving most text at the user’s chosen sizes, you’re designing for yourself, not for the users.

  • Andrei

    Martin, thumbs up! :)

  • http://akindale.com brandaggio

    Interestingly, this is from the YUI fonts approach ( http://developer.yahoo.com/yui/fonts/ ):
    #demo1 {font-size:85%;} /*renders 11px */
    #demo2 {font-size:100%;} /*renders 13px */
    #demo3 {font-size:108%;} /*renders 14px */
    #demo4 {font-size:123.1%;} /*renders 16px */
    #demo5 {font-size:138.5%;} /*renders 18px */

  • jasonkarns

    @martin I’ll have to disagree with you. IE6 doesn’t support page zoom so if you have to support IE6 (which 99% of current web professionals do) then you’re forcing those users to read text that is possibly too little or too big to read.

    Secondly, page zoom will trigger horizontal scrollbars. I don’t know about you, but any site out there with horizontal scroll bars is a massive FAIL in my book. An em or % based layout & font-sizing solution, when text-zoomed, can prevent horizontal scroll bars.

    Lastly, defending your practice of user-unfriendly design by pointing to popular portals is akin to saying font tags and image-maps are professional ‘best practices’ simply because the popular portals use them. I doubt you’d ever hear a user complaint even if you used a static image map for your site because most users won’t bother. That’s why it’s our job to work FOR them and not force bad UI patterns on them.

  • anotheranonymous

    @jason,
    What techniques have you run into that would avoid horizontal scroll bars, granted relative font sizing? Being a user as well as a developer a lot of times I get mislocated data on popular websites just using Firefox. So it’d interest me your comments and experimentation here.

  • jasonkarns

    @anotheranonymous Tip for avoiding horizontal scrollbars: set a max-width on your container to some % less than or equal to 100%.

    I generally use em-based layouts with a max-width of around 90%. Even when using a px-based layout (width-wise only) I set a max-width of 100% on my container which (in many browsers) prevents horizontal scrollbars even when page-zoomed.