3 Must-Learn CSS Techniques for Perfect Web Typography

This article presents an extremely useful set of tips and best practices for those who are still fairly new to working with typography on the web.

We’ll go over the most popular methods for embedding web fonts, sizing fonts and setting a solid line-height.

19+ Million Digital Assets, With Unlimited Downloads

Get unlimited downloads of 19+ million design resources, themes, templates, photos, graphics and more. An Envato subscription starts at $16 per month, and is the best unlimited creative subscription we've ever seen.

Explore Envato Elements

Web Typography: The Basics

I started my design career in print so one of the most jarring transitions to the web-based mindset for me was in the area of typography. For print design, I can use any font I want on any piece as long as I own it and it is resident on my machine. Further, no one really cares how I size my fonts, as long as it prints big enough!

This article contains some techniques that I wish I had known right off the bat and had to learn the hard way through egregious errors and others that I’m only just now learning about!

Each of these three techniques might seem pretty basic to a pro, and are even likely to be debated by some, but I definitely recommend that anyone new to web design try to get a firm grasp of all these concepts so that you can choose a defendable position for how you set up your type online.

Embedding Web Fonts: Use @font-face

A year or two ago the web font game was pretty uncertain. Everyone knew a revolution was coming but there were a number of various techniques that were being pursued and few were certain as to where we would end up.

Fast-forward to now, a single solution has been widely agreed upon to be the best for many or even most circumstances. If you’re going to embed custom fonts into a website, @font-face is the way to go. It’s a pure CSS solution with awesome browser support and unlike Cufon and its cousins, results in perfectly selectable text that works and feels just like a native font.

Fontspring’s Bulletproof @font-face Syntax

This is a perfect example of how best practices in web design are constantly changing. The last I checked, Paul Irish’s smiley face bulletproof @font-face syntax was the best way to go. However, in researching this article I discovered that a new method has appeared that Paul Irish himself calls “the best possible solution.”

The new method is Fontspring’s Bulletproof @Font-Face Syntax, which addresses concern over the lack of support for Android in Irish’s original technique.

@font-face {
  font-family: 'Some Font';
  src: url('SomeFont.eot?') format('eot'), url('SomeFont.woff') format('woff'), url('SomeFont.ttf') format('truetype');
}

If you’re wondering about the question mark, it’s a clever trick to fool IE9 into submission with loading the proper fonts and avoiding a 404 error. For more on how this works, check out this post.

Two Free @font-face Services

If you’re looking to embed free custom fonts into your web page, the absolute easiest way that I’ve found is to use Google Web Fonts. This amazing service contains over 180 font families and requires zero file downloads on your part. Just browse the library, choose the fonts you want, then copy and paste the code snippets you’re given. It couldn’t be easier!

As an alternative, I always recommend FontSquirrel. Here you have to download @font-face kits, which is a little more work, but the payoff is an unbeatable collection of beautiful free fonts and the ability to upload a single font file of your own which will automatically be converted into several formats and turned into a usable @font-face kit.

The Font Sizing Dilemma

While we’re on the subject of fonts, let’s briefly discuss font sizing. This is actually a much more fiercely debated topic than the previous one. The truth is, no matter which method you choose, there are plenty of web developers out there who will insist that you’re doing it wrong!

For the most part, “em” seems to be the popular choice. The bottom line is that using “px” results in fonts that don’t scale well in certain browsers. Kyle Schaeffer has an interesting article on why using percentages may be a better option, but from what I can tell, most folks are still in favor of “em” (or at least an em % hybrid).

Now, since “em” can be a bit awkward to work with, a common practice is to set the body font size at 62.5% and then to use “em” for everything else. The reason for this is that the results are easy to translate: 1.2em = 12px, 1.4em = 14px, 2.4em = 24px, etc.

Unfortunately, this method causes an odd compounding issue when working with multiple levels of parent/children relationships. Once you get a couple levels in, sizing with “em” becomes difficult. The workaround is typically to declare child elements at “1em”, but Jonathan Snook might have an even better solution.

Font Sizing with REM

The “rem” unit is from the CSS3 bag of goodies and sizes fonts relative to the root (html) rather than the parent, which avoids the compounding issue. Here is Snook’s syntax from his article Font Sizing With REM:

html { font-size: 62.5%; } 
body { font-size: 14px; font-size: 1.4rem; } /* =14px */
h1   { font-size: 24px; font-size: 2.4rem; } /* =24px */

The downside here is that you have to declare backups in “px” for, you guessed it, various versions of Internet Explorer. However, the result, according to Snook, is “consistent and predictable sizing in all browsers, and resizable text in the current versions of all major browsers.”

Trouble in Paradise

As I mentioned above, there’s always someone around to say “that’s not right!” Developer Harry Roberts recently published an article at CSS Wizardry outlining why sizing with “rem” can be avoided. His argument is that the 62.5% trick arises out of laziness on the part of developer (a good thing according to Roberts) but ultimately results in more work (a bad thing).

Roberts goes on to argue against setting arbitrary base font sizes that you don’t need or even really use and instead encourages setting your base where you want it and styling only the exceptions.

Both developers have perfectly valid points. Snook’s method is certainly easier to figure out but Roberts makes a somewhat convincing argument for avoiding the 62.5% trick altogether. You should definitely take a close look at both and decide which one you can wrap your mind around!

Unitless Line Height and Typographic Grids

The last thing I’d like to go over is something that I didn’t even know existed until recently: unitless line height. Eric Meyer explains this idea in detail here, but I’ll give you a quick overview.

The concept here is a little hard to understand but bear with me. Basically, if you declare line-height with a united value such as “1em”, that computed value is then automatically passed down to its descendants. Here’s the example that Eric Meyer cooked up:

ul {font-size: 15px; line-height: 1em;}
li {font-size: 10px;}
small {font-size: 80%;}

This seems correct enough at first, but the result is actually grabbing the line-height of the child elements from that computed parent value. Therefore, the above code is exactly the same as if you had written this:

ul {font-size: 15px; line-height: 1em;}
li {font-size: 10px; line-height: 15px;}
small {font-size: 80%; line-height: 15px;}

Notice how the line-height stays at 15px for all of the elements. To avoid this, Meyer suggests using unitless line-heights, which are used as a multiplier for the line-height of the child elements. Here’s the example above rewritten to utilize this technique:

ul {font-size: 15px; line-height: 1;}
li {font-size: 10px;}
small {font-size: 80%;}

The result for the code above is exactly the same as that of the code below. From this we can see that our line height of “1” is being multiplied by the font-size of the li and small elements and the results are much more predictable.

ul {font-size: 15px; line-height: 1;}
li {font-size: 10px; line-height: 10px;}
small {font-size: 80%; line-height: 8px;}

Notice here that the line-height stays equal to the font-size of each element. It’s important to understand that this isn’t an argument for setting your line-height to exactly your font-size, this was done only for the example. Any number can be used for the line-height and you should experiment to find what works best (the next example uses 1.231).

HTML5 Boilerplate Approved!

To see if this is a common practice, I downloaded a copy of HTML5 Boilerplate and poked around in the CSS. Sure enough, right away I found a unitless line-height in practice, albeit in a more concise, shorthand version.

body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */
select, input, textarea, button { font:99% sans-serif; }

Creating A Typographic Grid

If you really want to dive into creating nice web typography, check out Richard Rutter’s article, “Compose to a Vertical Rhythm”, which outlines some useful techniques for juggling font size, line height and margin or padding to create a perfect rhythm for your page.

Chris Coyier over at CSS-Tricks picks up this technique and takes it further by combining it with, wait for it, unitless line-height! Check out this page where you can view and download Chris’ prefab typographic grid utilizing these methods.

Conclusion

These three lessons can be summed up nicely. First, when you’re embedding fonts on the web, use @font-face for a highly functional, cross-browser solution. For now, Fontspring’s syntax seems to be the best solution for formatting your @font-face declarations. Google Web Fonts and Fontsquirrel are the places to go if you want free web fonts that can be easily inserted into any page.

Next, since “px” can and does have trouble resizing on various browsers, using “em” or “rem” for font sizing is probably the best way to go. Using “rem” allows for easy use of the 62.5% trick without compounding issues, but there is a decent argument against abandoning this technique, setting an intentional base font-size and doing the math manually for any exceptions such as headers.

Finally, when working with line-height, it’s a good idea to set up a vertical rhythm or all out typographical grid. One important method to keep in mind is the use of unitless line-heights to simplify inheritance.

These are current best practices as far as I see them. Feel free to leave a fierce rebuttal in the comments for any and all of these techniques. I love digging into and learning about this stuff and if you have alternative methods I want to see them!