Skip to content
Accessibility HTML and CSS

Using Scalable CSS Units for Font Sizes

6 min read

When you're setting the font sizes in your stylesheets which CSS measurement do you use and is it restricting the usability of your site?

Using px Units

I regularly come across people defining their font sizes using pixels. It's easy to understand why: they make matching the font sizes to a design simple and you don't have to think too hard and calculate things.

The problem is pxs can be a bit limiting:

  • They limit usability by preventing users of Internet Explorer older than version 10 from using the text resize feature (an important accessibility tool).
  • They make changing font sizes in a responsive design more challenging.

Using em Units

A more suitable CSS unit for font sizes is the em. The em is a scalable unit, 1em is equal to the current font size; so if the parent's font size is 16px, 1em is 16px and 2em is 32px. The important thing to remember is that the em unit is relative to its parent.

By setting the base font size and then defining the font sizes of the elements on the page in em we can relatively easily get Internet Explorer's text resize feature working. For this we want to set the base font size using a percentage, and then the elements of the page using em:-

html { font-size: 100%; // this is usually 16px by default }
body { font-size: 0.75em; // 12px }
h1 { font-size: 2em; // 24px }

Alternatively, we could have set the base font size to 12px straight off using a percentage. This way 1em equals 12px to start with.

html { font-size: 75%; // 12px }
body { font-size: 1em; // 12px }
h1 { font-size: 2em; // 24px }

Defining the font sizes this way a user will be able to use IE's text zooming.

If you find converting from px to em taxing there are a number of sites out there to help you, for example PXtoEM.com.

If you're looking at this and thinking what a hassle I'll stick to px, who cares about Internet Explorer or its text zooming tool, look at it another way: using scalable font sizes is great for responsive web design!

Responsive web design has become a big deal in the last couple of years. Using media queries is not all about changing the page layout; you can change the font sizes to be more suitable for the device the page is being viewed on too. For example, if the screen size is small you may want to increase the font size to make the text more comfortable to read on a small device like a mobile:-

html { font-size: 75%; // 12px }
@media only screen and (max-device-width: 480px) {
	html { font-size: 100%; // 16px }
}

In this example we increase the base font size when the device width is 480px or smaller and then our ems will scale accordingly.

There is a problem with the em unit though: it's relative to it's parent so you have to be careful of nested elements and the stylesheet's cascade. For example, consider the case of a list (<li>):-

html { font-size: 75%; // 12px }
body { font-size: 1em; // 12px }
li { font-size: 0.833em; // 10px }

If we have a list within a list, the nested list will have a font size of 8px not 10px as might have been required.

If you're using ems you must remember to take into account the cascade effect. However, there is an alternative CSS unit that solves this problem and maintains the scalability of an em, the rem.

Using rem Units

Like ems, rems are a scalable CSS unit but are more robust and predictable. Introduced as part of CSS3, rems ('root em') are relative to the root (the <html> element) rather than the parent. This instantly makes life much simpler.

Let's modify the CSS used in the last example for a list to use rem:-

html { font-size: 75%; // 12px }
body { font-size: 1rem; // 12px }
li { font-size: 0.833rem; // 10px }

Not much has changed. We're still setting the base font size using a percentage to set it as 12px, but now our other font sizes use rem relative to the base font. If we have a list inside a list with our updated styles the list elements will all have an equal font size of 10px. Result!

You can still use tools like PXtoEM.com to calculate your font sizes. rems are just like ems except relative to the base font on the <html> element. If you're using a CSS pre-processor like Sass it's even easier as you can use a mixin for your font sizes. For example:-

$base-font: 12px;

@mixin font-size($font-size){
    font-size: $font-size;
    font-size: ($font-size/$base-font-size)*1rem;
}

li {
    @include font-size(10px); 
}

Unfortunately, despite having fantastic support from modern browsers the rem unit didn't appear in IE until version 9. So if you need to support IE8 or lower this isn't going to work.

If you are prepared to sacrifice the ability to use IE's text zoom (and remembering anything below IE9 doesn't support media queries) you can use rem with a fallback. In the Sass mixin above we've set the font size in px before setting it again in rem; so for older browsers the font sizes will be correct, but modern browsers will get the benefit of using rem.

So Which CSS Measurement Should You Use?

Personally I think if you're still using pxs for font sizes it's time to stop. Get into the habit of using a scalable font size as they're where the future lies. They make responsive font sizes simple and enable the user to use text zooming for accessibility.

I have been using em for a number of years now, partly due to working on a number of sites where accessibility was of great importance. I'm now moving towards rem as they're simpler and I want to be able to easily modify my font sizes based on the base font.

Whether you use em or rem really depends on the project and requirements of the client/users. If you need to support IE8 (or lower, poor you) go for em. Otherwise, get on board with CSS3 and start using rem.

If you want to know more about CSS measurements and which to use when I'd recommend taking a look at Dudley Storey's Which CSS Measurements To Use When.

© 2024 Andy Carter