Thursday, June 6, 2013

Typography on the web: ems and rems

Typography on the web needs to be flexible, especially as the demand for responsive web design grows. Although most of us are familiar with pixels they aren’t necessarily the most versatile unit of measurement out there. This is especially notable when viewing content on mobile phones and tablet devices. Pixels, like inches, are absolute units. By contrast, the em is a relative unit and can easily be scaled to fit proportionally with everything else on the screen, regardless of where it’s being viewed.

Since the em is an adaptive measure, it is proportionally the same at any size. One em is always equal to the type size. In 12px font size, 1em is 12px and in 50px font size, 1em is 50px. The em is calculated based on the font size of the parent element. For example, if a <div> has its font size set to 20px then any elements inside of that <div> will inherit its font size. If we set a <p> inside the <div> to 0.7em then it will display at 14px.

All browsers display text at a default size which varies widely among devices. For example, most desktop browsers default at 16px while many mobile browsers come standard at 12px. That’s a big difference when dealing with small screens. Instead of declaring absolute, pixel-based font sizes for each element in each unique query you can use ems to adjust font sizes across the board and on the fly. All it takes is a simple css declaration of what an em is.

However, since the em is computed relative to its parent, you must take careful note of the current parent’s font size to know what font size your element will be. In addition, cascading can cause issues. What happens with you have a list nested inside a list? Or a paragraph within a list? The font size will compound, resulting in something other than your desired size.

A solution to this issue is the rem*, or root em. As the name suggests, this unit is relative to the root, rather than the parent element, avoiding any type of compounding. Once you define a font size for <html> you can apply font sizes that will always be relative to this value.

The rem can prove to be very useful for typography but when working with proportional whitespace (i.e. padding and margins) that surround typographical elements, ems work much better. Using em units allow the padding and margins to scale with your font size whether it goes up or down. For example, when setting the padding around your header, using ems will enable the amount of space to be dependent on the font size of the header, not on the root’s size.

Calculation examples
To convert your pixels to ems or rems you can use the following equation, which evaluates the relationship between your desired font size to the parent’s/root’s font size:

desired pixel size / inherited or root pixel value = em value

The following is an example of using the equation to set header font sizes in ems, assuming the browser's default font size is 16px:

body {font-size: 100%;}
h1 {font-size: 2em;} /* 32 / 16 */
h2 {font-size: 1.5em;} /* 24 / 16 */
h3 {font-size: 1.25em;} /* 20 / 16 */

It is important to remember that the font-size is determined relative to the font-size of its parent, which may not be the body font-size. If any of these headers are inside of an element with a set font size, the result would be different and the use of a rem (see CSS below) may be more appropriate.

html {font-size: 100%;}
h1 {font-size: 2rem;} /* 32 / 16 */
h2 {font-size: 1.5rem;} /* 24 / 16 */
h3 {font-size: 1.25rem;} /* 20 / 16 */

*Browser restrictions for the rem
The root em was introduced with CSS3 and therefore it does have some browser restrictions. Currently the following browsers support rem: IE 9, 10, Firefox, Chrome, Safari, and Opera (see: http://caniuse.com/rem). A fallback option for older versions of IE of is pretty simple - revert back to ems or pixels.

html {font-size: 100%;}
h1 {font-size: 32px; font-size: 2rem;} /* 32 / 16 */
h2 {font-size: 24px; font-size: 1.5rem;} /* 24 / 16 */
h3 {font-size: 20px; font-size: 1.25rem;} /* 20 / 16 */