Communication Through Typography

ancient Roman typography

Looking for the lessons? Get started!

A look at fonts and typography for Web sites.

The entire Web Design Principles section can be accessed through the menu below.

Unfortunately, not everyone's browser will support the spiffy JavaScript menu behind that innocent-looking button. If your browser won't display the menu, just click on the button and you'll be taken to a separate page with the entire menu displayed in clear, non-JavaScript HTML.

Web design is 95% typography. — Oliver Reichenstein

css icon

Before we broach the subject of fonts and typography, let me make one thing very clear:

The only fonts your site visitors will see is the ones they have on their browsers.

This seems to be a concept that a lot, and I mean a lot, of burgeoning Web designers have trouble grasping. It's easy for us to get caught up in what we see on our displays, and we forget entirely that others won't see those fonts.

"Let's see, I'll make my heading in Monotype Corsiva because I love that beautiful handwriting appearance. I've got this font called Adobe Caslon which will go perfectly with that calligraphic heading for most of my text, and I'll use this lovely Futura sans-serif for contrast. What a beautiful site!" Yes, and most of your site visitors will see everything in whatever boring default font their computer has. Why? Because they don't own those fonts.

Web-Safe Fonts

Therefore, there's a lot more to choosing fonts than merely picking a font you like from Microsoft Word. There are really only a few fonts that work on (almost) all systems, from Windows to Mac and Linux. These are called "web-safe" fonts because you can expect that, when you use them, almost all the people who visit your site will see it in the font you like.

If you don't have Microsoft Word on your machine, try using your word processor or text editor to display the fonts. If you don't have one of those, then you'll have to go through your machine's Fonts applet (or your equivalent) to display your fonts. There are also a lot of free font utilities on the Internet to manage and display the fonts on your machine. One simple one I can recommend for Windows users is Free & Easy Font Viewer. A free utility for Mac and Linux users (and Windows, if they choose) is Opcion.

Here's a list of the "web-safe" fonts, from WebDesignDev and my own SitePoint article. (All the images are public-domain PNGs from Wikimedia.) The fonts in italics can be found on 95%+ of the computers in existence. The others are on a strong majority of systems, and can be used to base your font-family "font stacks" on as well.

The Four Types of Fonts

Serif Fonts: Copperplate Gothic Light, Georgia, Palatino Linotype, Times New Roman (pictured below)

An example of a serif font Serifs in red

In the second illustration, the serifs of the font are marked in red.

Sans-serif Fonts: Arial, Arial Black, Arial Narrow, Century Gothic, Gill Sans, Lucida Sans Unicode, Tahoma, Trebuchet MS, Verdana (the illustration below depicts Helvetica, a Mac font very similar to Arial)

An example of a sans-serif font

Monospace Fonts: Andale Mono, Courier New (pictured below), Lucida Console

An example of a monospace font

Cursive and Fantasy Fonts: Comic Sans MS, Impact (not sure what font is depicted below)

An example of a fantasy font

Only about half of these fonts can reasonably be used to create "font stacks" for your pages, particularly your body text — you don't want to sacrifice readibility for appearance. That's why three relatively boring fonts — Verdana, Arial, and Arial's Mac cousin, Helvetica — are perhaps the most popular body text fonts in use today.

Font Stacks Using @font-family

Creating "families" of fonts in what we call @font-family groups, after the CSS property, is something designers argue over at length. But, everyone appreciates a starting place.

Here are some very simple, basic suggestions for font stacks you might use in your designs. Remember, these are suggestions. Take them, use them, think about them, and change them as needed.

The basic formula is simple: Start with a font you like, then give a close alternative that others will see if they don't have the font you like, then give a more universal (web-safe) alternative, and finally end with the generic "serif," "sans-serif," or "monospace" font name. Remember, the universal fonts go at the END of the stack, not the beginning!

Notice that all fonts that have more than one word must be enclosed in quotes, with the comma outside the closing quote: for example:

"Times New Roman", serif.

Serif Fonts

A good serif font stack to start with might be:

font-family {
   Georgia, "Times New Roman", serif;

What you're telling the browser: "Use Georgia to display this text. If you don't have Georgia on your machine, use Times New Roman. If you don't have that, either, use whatever default serif font you have."

Here's a serif font stack I sometimes use, beginning with a Microsoft Vista font, following with two serifs often used on Linux machines, and finishing with the two universal fonts:

font-family {
   Constantia, "Liberation Serif", "Nimbus Roman No9 L Regular", Georgia, "Times New Roman", serif;

Note: Georgia looks better than Times New Roman on the Web, and should be used in preference, i.e. before Times New Roman in your stacks.


A good sans-serif font stack might be:

font-family {
   Helvetica, Arial, sans-serif;

Here's a sans-serif font stack I sometimes use, again beginning with a Microsoft Vista font, following with two sans-serifs often used on Linux machines, continuing with a widely used Mac font, and finishing with the near-universal Arial:

font-family {
   "Segoe UI", "Liberation Sans", "Nimbus Sans L", Helvetica, Arial, serif;

Verdana is perhaps the most widely used font on the Internet, because it is so readable and easy on the eye. It's a good bit wider than the relatively narrow Helvetica/Arial combinations. Here's a Verdana-based stack you might consider, starting with a popular Mac font, moving to two Linux fonts, and ending with Verdana:

font-family {
   "Lucida Grande", "DejaVu Sans", "Bitstream Vera Sans", Verdana, sans-serif;

Many experts believe that sans-serif is a better font choice for large blocks of text (say, paragraphs) that serif. I'll let Ian Lloyd explain:

A serif font is one that has all those little flourishes at the ends of each letter. These flourishes ... are known as serifs. They're great for reading printed material, as they give a little shape to the words, making them easier to read. However, on the screen, serif fonts can become a little messy, especially when they're used for smaller type — there simply aren't enough pixels on the screen to do these little flourishes justice. For this reason, you’ll notice that many web sites use sans-serif fonts (from French, translating as 'without serif') when the font size is set quite small.

Serif fonts are excellent for headings and blocks of text intended to be displayed in larger sizes, and with fewer words included.

Does everyone agree with this? Not at all. For a single example out of many, my friend Vivien, in her site Inspiration Bit, gives us an excellent compendium of 32 sites designed around the Georgia font.

Monospace Fonts

Monospace fonts are used primarily for presenting code and other "fixed-width" text. (You're seeing the code on these pages in either Consolas, Andale Mono, Lucida Console, or Courier New, depending on what's on your machine.) A good monospace font stack might be:

font-family {
   "Andale Mono", "Courier New", monospace;

Here's a monospace font stack I sometimes use, again beginning with a Microsoft Vista font, following with two sans-serifs often used on Linux machines, and finishing with two web-safe fonts:

font-family {
   Consolas, "Liberation Mono", "Nimbus Mono L", "Andale Mono", "Courier New", monospace;

Fantasy/Cursive Fonts

It's tough to create a fantasy or cursive font stack that will show up on most computers. The only two that are widely used, Impact and Comic Sans MS, are very, very different in appearance; Impact is a heavy, compressed font sometimes used for headings, and Comic Sans MS, created to give the appearance of "comic-book" lettering, has been so terribly overused and misused that many designers refuse to use it at all.

Warning: A lot of people don't like the Vista fonts (I used Constantia, Segoe UI, and Consolas in my examples). If you find they don't look good in your designs, take them out!

A lot of designers like to combine serifs and sans-serifs in their designs. For example, the design for this site uses Georgia, a "universal" serif font, as its base, and a sans-serif, Helvetica Neue, as the font for its central body content. (You're reading this in Helvetica Neue right now, or, if your machine lacks that font, either Helvetica or Arial.) The combination of serifs and sans-serifs seems to work very nicely in most designs.

Making Font "Shortcuts"

Like some other CSS properties, you can make "shortcuts" out of multiple font properties. (Some people call this "shorthand".) For example:

.regtext {
   font-weight: bold;
   font-size: 14px;
   font-family: verdana, arial, sans-serif;

can be shortened:

.regtext {
   font: bold 14px verdana, arial, sans-serif;

The folks at Tech-Evangelist, whose shortcuts I cribbed, remind us:

Not all related CSS rules can be combined into a shortcut, but many of the most commonly used rules can be condensed into a single line. You do need to be aware that order in which you place the CSS values does make a difference. Also, CSS shortcuts should be tested in a range of browsers because CSS rules are not always interpreted the same. Internet Explorer 6 is very buggy when it comes to rendering CSS rules properly. You should test all style sheet code in all of the most popular browsers...

Designer Louis Lazaris has provided us a nifty downloadable chart to help us keep the shorthand orderly and functional.

Styling and Sizing Your Fonts

There are several ways to control the appearance of a font. Four of the most common are listed below:

  • Font Size
  • Font Style
  • Font Weight
  • Font Variant

Let's look at each of these in turn.

Font Size

The meaning of the CSS attribute font-size is pretty obvious. It controls the size of the font as it appears on your display. There are several ways to choose the size of your font: pixels, ems, percentages, and keywords. You might want to review the section on units of size:

More about units of measuring size.

Pixels are absolute across all browsers. Setting your font's size in pixels prevents some browsers, particularly Internet Explorer 6 and7, from allowing a user to resize the font using the text-resize function in their browsers. Firefox and Safari users can resize pixel-defined fonts, while Opera and IE7 users have a "zoom" function that resizes the page quickly and easily, text included. One popular "baseline" font size is 16px:

body {
   font-size: 16px;

Ems are relative units of measurement. It is considered best practice to use ems whenever possible in sizing fonts (and other Web elements). It is scalable, which means that it resizes relative to its parent element. (Confused yet?) If you set a font size on the body, or even better, if you don't set a font size on the body, thereby leaving it up to the user's own preferences, the subsequent font elements — headings, paragraphs, list items, margins, paddings, and the like — will resize relative to that original "parent" size.

We'll go back to the popular 16-pixel base size for our example. If your user has chosen 16 pixels as his base font size (or more likely, your user hasn't chosen anything and left it to his browser default), everything you size will be relative to that 16px base. For example:

h1 {
   font-size: 2em;

h2 {
   font-size: 1.5em;

p {
   font-size: .9em;

ul li {
   font-size: 1.2em;

makes the following size choices:

  • Your h1 elements will be twice the size (2em) of the base font size of 16px — in essence, 32px.
  • Your h2 elements will be 1.5 times the size (1.5em) of the base font size of 16px — in essence, 24px.
  • Your p elements will be .9 times, or 90% (.9em) of the base font size of 16px — about 14px.
  • Your li elements (in your ul) will be 1.2 times, or 120% (1.2em) of the base font size of 16px — about 19px.

Change the base font size from 16px to something else, say 12px, and the relative sizes change as well:

  • Your h1 elements will be twice the size (2em) of the base font size of 12px — in essence, 24px.
  • Your h2 elements will be 1.5 times the size (1.5em) of the base font size of 12px — in essence, 18px.
  • Your p elements will be .9 times, or 90% (.9em) of the base font size of 12px — about 11px.
  • Your li elements (in your ul) will be 1.2 times, or 120% (1.2em) of the base font size of 12px — about 14px.

(See below for a different take on using ems in your layout.)

Percentages are quite similar to ems in their effect on your font sizing. Percentages work like so:

h1 {
   font-size: 200%;

h2 {
   font-size: 150%;

p {
   font-size: 90%;

ul li {
   font-size: 120%;

Yahoo Development Network gives us a useful chart that tells us what percentage to use to get our fonts at a particular pixel size, i.e. 16px=123.1%. The chart assumes a default of 13px and a 16px line-height, and assumes the user has not altered the browser or monitor defaults.

Of keywords, web designer Chris Coyier writes:

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.

Of point sizes, Coyier writes emphatically:

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. … [T]he reason we don’t use point sizes for screen display (other than it being absurd), is that the cross-browser results are drastically different.

In general, the ability for the user to resize fonts is critical. Useability guru Jakob Nielson writes:

CSS style sheets unfortunately give websites the power to disable a Web browser's "change font size" button and specify a fixed font size. About 95% of the time, this fixed size is tiny, reducing readability significantly for most people over the age of 40. Respect the user's preferences and let them resize text as needed. Also, specify font sizes in relative terms — not as an absolute number of pixels.

Font Style

This seems a bit generic of a term to use, considering everything we're doing is "styling" fonts. But this font attribute simply controls whether the font presents itself as normal (the default value), italicized, or oblique:

p {
   font-style: italic;

h4 {
   font-style: oblique;

The oblique value isn't used often, mostly because a lot of fonts don't have an oblique version. Most browsers use italics as a substitute for obliques. (What's an oblique? That style slants letters slightly differently from italics. The difference is minute but discernible.)

Font Weight

The font-weight attribute helps you decide how much "weight," or thickness, to add to a font. It gives you some finer control than the usual "boldface," or HTML <strong> </strong> tag. Basically, it goes from 100 to 900 in gradations of 100 (in other words, a font-weight of 247 won't be of any use). Stick to 100, 200, 300, and so on.

Many browsers won't display a lot of difference between the 100s, either. While you can use them if you like, you'll probably be just as well served sticking to the three most popular font-weight values: 100 (light), 400 (normal), and 700 (heavy, or bold):

p {
   font-weight: 100;
p {
   font-weight: 400;
p {
   font-weight: 700;

You can also use keyword values such as bold, bolder, and normal, but few designers use these.

Font Variant

There is only one "variant" in the font-variant group, the ability to have fonts appear in small caps. Not every font supports small caps. Here's how to use it:

p {
   font-variant: small-caps;

The 62.5% Method of Sizing Fonts

I know I talked about font sizing just above, but this is tricky enough to warrant its own section.

This information is based on the excellent book by Craig Grannell that I reference throughout this site, a blog post by Trevor Davis, and two articles by the inventor of this technique, Richard Rutter.

Basically, the idea is to set your base font size in your body (or whatever other governing element you choose to use, i.e. your wrapper) to 62.5%. This causes your base font size to display at 10 pixels in most browsers. By doing this, 1em of size is equivalent to 10px.

Designers do this primarily because Internet Explorer won't resize text set in pixels. Some later versions of IE will "zoom" the entire page, but that pain-in-the-rumpus browser won't resize just the text, like just about every other browser does.

Rutter writes:

Text for the screen is sized with CSS in terms of pixels, ems or keywords. As most of us know, sizing with pixels is easy: get your selector and give it a font-size — no more thought required. Sizing with keywords is more complicated and requires a few workarounds, but you're in luck as the techniques are well documented. That leaves ems. At this point people often leg it. "Ems are too inconsistent," they say, "they're too hard; they never work." ... If the world were an ideal place, we'd all use pixels. But it's not, we have the broken browser to contend with. IE/Win will not allow readers to resize text that has been sized in pixels. Like it or not, your readers will want to resize text at some point. Perhaps they are short-sighted, doing a presentation, using a ridiculously high resolution laptop or simply have tired eyes. So unless you know (not think) your audience won’t be using IE/Win or will never wish to resize their text then pixels are not yet a viable solution. ... Using ems however, allows all browsers to resize text and also provides pixel-level precision and so they tend to be my unit of choice.

Davis notes that he does something slightly different:

Although I typically then set my container font-size to 1.2em, which in turn sets the font-size to 12 pixels. But still, then you know that 1em is equal to 12 pixels.

Rutter agrees, noting that "10px text is too small for the real world." Using his technique allows us to do the following:

1em is 10px, 0.8em is 8px, 1.2em is 12px, 1.6em is 16px, and so forth.

You have to size the individual elements — the paragraphs, headings, list items, etc — but this method gives you a great deal of control over your font sizes, and enables you to use ems quickly and easily. Basically, Rutter has done the math for you.

This isn't a foolproof method by any stretch: there are issues with it, which is why many designers (including myself, at least as of this writing) don't use it. (One problem is that ems cascade and pixels do not, which means that if you size your body fonts at, say, 1.3em and your h1 at 1.5em, your h1 will display at 19.5px, not 15px as you may have planned. Kudos to Will Bond for pointing this out. And SitePoint adviser Stephen Chapman notes that 1em won't necessarily equal 10px unless the user's screen resolution is set to 1em=16px, which it often is, but not always. In a related SitePoint thread, design adviser Paul O'Brien gives an excellent method of setting all browser displays to a default of 13px.) But many, many designers swear by it. You may well adopt it for your own purposes.

One excellent source of information on this method, and the use of ems in general for sizing fonts, is Jon Tan's article on ems and elastic layouts.

Further Reading

Reading Jon Tan is a must for anyone interested in the finer aspects of typography and fonts for the Web. (And check out the subtly elegant site design while you're there.) If you're not sure where to start, try this entry first, and go from there.

Typography maven and Web design expert Jason Santa Maria gives us an excellent overview, with detailed examples, for using a variety of fonts in your designs.

The CSS3 @font-face property is an exciting way to use many, many fonts in your designs that your users don't have. There are issues surrounding its usage, but it may well open up the Web to an entire new world of fonts and typography. You can begin learning about the subject at Font Squirrel, which gives you an incredibly easy way to use this property (and some excellent fonts) in your designs, and you can learn more about it at