CSS Typography: The Basics

CSS Typography: The Basics

Typography is an essential component of a website’s design. This is for good reason: good typography is not only imperative for aesthetic appeal, but also improves site usability when text legibility and readability concepts are applied. Typography is all about proportions and spacing. There are also font styles to consider.

How can we use CSS for great typography in our web designs? This is a question we’ll try to answer.

This is the first part of a three-part series of guides on CSS typography that will cover everything from basic syntax to best practices and tools related to CSS typography.

Typography CSS Properties

There are two main groups of CSS properties that control typography style: font and text.

The font CSS property group dictates general font characteristics such as font-style and font-weight. Below you’ll see the p element given a font-style and a font-weight property.

p {
  font-style: oblique;
  font-weight: bold;

The text CSS property group deals with the characters, spaces, words and paragraphs. For example, the text-indent property indents the first line of a text block. The letter-spacing property controls the spaces between a text block. Below, you’ll see the p element given a text-indent and a letter-spacing property.

p {
  text-indent: 50px;
  letter-spacing: 2px;

There are other CSS properties that can affect web typography outside of the fonts and text property groups. For example, the color property controls an HTML element’s foreground color, and can be used to change the color of text. Below, you’ll see the p element given a red color.

p {
  color: red;

Font Sizing

Browser compatibility is a major issue in web design, even more so if you are attempting to make your web designs look the same in all browsers. Beginning web designers may mess around with a font’s size until it looks just right, only to find it has completely changed among other browsers and platforms. Size fonts the correct way, and this problem can be minimized.

A simple use of sizing text is as follows:

h6 {
  font-size: 12pt;

The above sets the heading level-6 element to 12pt.

For font-size values, there are 4 types of units of measurement.


Standard keywords whose values are defined by the user agent (e.g., web browser). Values in W3C CSS 2.1 specifications are xx-small, x-small, small, medium, large, x-large, xx-large.


Standard keywords that size fonts based on the parent element. These are also defined by the user agent. Possible values are larger and smaller. Below you will see what a paragraph element looks like inside a parent element (<div>) that has a size of 12pt (in Firefox).

div {
  font-size: 12pt;
p {
  font-size: large;

Both keyword value groups (absolute-size and relative-size) can vary greatly between different browsers, so if your aim is to be pixel perfect, they might not be a good option, and most web designers avoid them altogether.

The smaller and larger keywords, however, can be great for convenient relative sizing when exact proportions don’t matter to the design. The larger and smaller values will inherit the parent element’s font-size and then relatively adjust the target element’s font-size accordingly. So, for example, if a parent element’s value is set to small, the larger keyword will make the child element larger. For most browsers, the change from exact units is around 1.2 units, although that proportion is not consistent amongst all browsers.

As an example, if text is set to 12pt, the larger keyword will resize the child element’s text to about 12pt x 1.2 (depending on the browser), which would equal 14.4pt.

Absolute Lengths

Absolute lengths are literal sizes. For example, 12px is exactly 12 pixels and 2in is exactly 2 inches. Absolute lengths are often used by web designers.

Possible units for absolute length units are pt, px, mm, cm, in, and pc.

Millimeters (mm), centimeters (cm), and inches (in) are more suitable to physical, real-world dimensions and are units of measurement often used in print design. They are not very suitable for screen-based measurements because of the high variance of screen resolutions.

Points (pt) and picas (pc) — while better than mm, cm and in — can also vary visually based on the browser or device’s dpi.

Therefore, when using absolute lengths, pixels (px) are the least problematic. One issue with px, though, is that older versions of IE cannot resize them natively. If developing for an audience that will likely resize text manually through their web browser, the px unit of measurement may not be a good option. Be sure when using px for font sizing that accessibility is not an issue.

Relative Lengths

The other type of length units are relative lengths. This means that their sizes are dependent on the font-size assigned to their parent element. Possible units are em, % and ex.

Not many web designers use ex — it is the height of the letter "x" in the current font.

em and % values are far easier to work with. em and % act identically, and it’s just a matter of syntax:

html, body {
  font-size: 85%; /* = (.85em) */

h1 {
  font-size: 110%; /* = (1.1em) */

The proportions are all relative to the element’s parent font-size. So, if the base font size (in body or html) is set to 80%, a child with a font-size of 0.2em or 20% would be 20% in height of the original 80%.

Font Stacks

CSS font stacks are a list of fonts that include fonts that will work well in various operating systems and platforms, with the goal of making typography as consistent as possible.

Here is an example of a font stack:

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

In the above example, the web browser will go from left to right until it finds a font in the user’s computer. For example, it will search for the Georgia font, and if it doesn’t find it, it will move on to the Times font, and so on.

There are many options for creating font stacks, and there are many popular premade font stacks available on blogs and in IDEs such as Dreamweaver.

The idea of a font stack is to provide ideal fonts that would be available on many computers, and then provide fallback fonts behind them to degrade to in case the preferred font is not available.

A good goal to strive for is to create beautiful typography for a wide range of users, but also account for the situation that the preferred font is not available to all users.

There are a few key items to keep in mind when creating custom font stacks:

  1. There should be a good amount of fallback fonts. Our above example only lists three, but it would be ideal if there were more.
  2. The fonts selected should be available on a number of platforms. For example, Arial is widely used on Windows, while its near equivalent, Helvetica, is on nearly all Macs.
  3. For font stacks that accomodate Linux users, check out A Web Designer’s Guide to Linux Fonts.

Best Practices for Developing Font Stacks

All fonts in the same font stack should have the same (or similar) aspect ratios. Some fonts are wider or taller per letter than others are, giving them larger aspect ratios.

So, if we put Verdana (mostly Windows) with Helvetica (mostly Macs), we’ve met the above requirements. However, since Verdana is much wider than Helvetica, the text will look dramatically different on most Macs compared to most Windows computers.

The image below show the difference in aspect ratio among four common Windows fonts. As you can see, Verdana and Georgia are wider and taller than both Arial and Times.

In larger blocks of text, the difference is more apparent. If we had a font stack with Verdana to accommodate Windows and Helvetica for Macs, the image below shows the significant difference.

So when developing font stacks:

Here is a list of the most common fonts for various aspect ratio types:

If you need more help on font stacking, CodeStyle has created a very useful font stack builder that includes all fonts between Mac, Windows, and Linux.

CSS Typography Pseudo-classes and Pseudo-elements

CSS pseudo-classes and pseudo-elements are great for targeting certain types of elements. Pseudo-classes start with a colon (:) followed by the class/element name.

There are several CSS pseudo-classes/pseudo-elements related to typography, such as :hover and :first-letter.

Let’s go over some that will help in styling our typography.

Links and Dynamic Pseudo-classes

The design of a website’s hyperlinks is very important. Use anchor link pseudo-classes to create font styles for each link state.

:hover is probably the most familiar, and it is good practice to create a separate (yet similar) style for it to provide a visual cue that a link element is interactive.

Here are the link pseudo-classes:

a:link { color: #666666; text-decoration: none; }
a:visited { color: #333333; }
a:hover { text-decoration: underline; }
a:active { color: #000000; }

First, Last, and n-th Pseudo-elements

The following pseudo-elements all relate to the position of an element relative to the HTML document and the other HTML elements in it.

:first-letter allows you to target the first letter of an element. Here’s an example:

p:first-letter {
  font-size: 30pt;
  display: block;
  float: left;
  margin: 0 5px 5px 0;

As you can see, this pseudo-element can be helpful for creating drop caps.

The ::first-line CSS pseudo-element allows you to select the first line of an HTML element containing text. Here’s an example for bolding the first line of text and making its letters uppercased:

p::first-line {
  font-weight: bold;
  text-transform: uppercase;

Note: As of Aug. 15, 2015 Google Chrome has a bug where the text-transform CSS property is ignored when using the ::first-line pseudo-element selector.

:nth-child() is a CSS3 pseudo-element that will target that nth element in a page or parent element depending on the selector’s specificity. In our example below, we target the second paragraph on the page.

p:nth-child(2) {
  background: #e7f0ce;
  padding: 10px;

We could also target the second paragraph within a div or the second list item in a list as follows:

div p:nth-child(2) { 
  background: #e7f0ce;
  padding: 10px;

ul li:nth-child(2) {
  background: #e7f0ce;
  padding: 10px;

Also play around with :nth-child(even) and :nth-child(odd) pseudo-classes to grab even and odd elements.

There is also the :first-child pseudo-element (CSS2) and the :last-child (CSS3) pseudo-element that can select the first and last element in a set.


We have covered the basics of CSS typography. With a bit of creativity, typography can go in some beautiful and interesting directions with CSS.

In the next part, we will discuss some CSS techniques and best practices pertaining to CSS typography.

Related Content

About the Author

Kayla Knight is a web designer and web developer who loves coding way too much for her own good. She does freelance design/development work and helps run the XHTML Shop. Connect with her by vis

This was published on Mar 3, 2011


Kristine Mar 03 2011

Thanks for sharing this info. You expressed it simply and concisely. Looking forward to the next CSS typography article.

Amos Vryhof Mar 03 2011

Nice article. I like combining some of these with @font-face to get some really nice looking paragraphs.

For the font stacks though, I usually borrow the ones listed in the “A Web Designer’s Guide to Linux Fonts” article that was on SR not too long ago. (

Can’t wait to see the other two parts!

Marcus Mar 03 2011

wow. a very good basic introduction. I can not wait for the 2nd part and i’m looking forward to the tools in the third part.

philipcaplan Mar 03 2011

For font stacks, I would warn against using the “fantasy” fallback in place of “serif” or “sans-serif”>

In Safari on my Mac, it substitutes a nice font.

In IE8 on my wife’s WinXP laptop, however, it uses an almost unreadable wacky font with what looks like half an old-fashioned alarm clock for an uppercase “C” !!

In fact, only “sans-serif” seems to be the safest cross-browser fallback option, because as the designer of a website you can never know how the viewers of your site will have their browser settings/preferences set.

Markus Mar 03 2011

good stuff ;) thanks

Tim Beglinger Mar 03 2011

Thanks, didn’t knew this whole ‘first letter & line’ stuff before.

Yusuf Akyol Mar 03 2011

Thanks very much. This article very useful for me. Will you add more?

Best regards.

Good writing! Love the hands-on. Especially the pseudo-part. Could become a good series, so can’t wait for the next episode

Young Mar 03 2011

FanTASTic. I don’t think I’ve seen a more comprehensive basic introduction on the web to this day. Well done Kayla and SR!

Michael Tuck Mar 03 2011

Kayla, this is a series I wish I had written. :) Since I didn’t, I will use it for teaching new designers. Looking forward to Parts 2 and 3!

Very useful :D

“Pseudo-classes start with a semi-colon (:) ”

Isn’t that a colon? A semi-colon is ;

Very nice article. One suggestion, since this is really a beginners overview, in regards to the “First, Last, and n-th Pseudo-elements” section, it might be good to disclaim that those nth selectors are useless if you plan to support Internet Explorer in any capacity.

hernan Mar 03 2011

Que lindo todo esto de las tipografias…. vos si que la tenes clara!!!!! buen articulo!

Sovetique Mar 04 2011

Great post! A lot of useful things I’ve found out. Thanks, Kayla, especially for pseudo-classes mentioning. ;-)

Raghav Mar 04 2011

hay simply and cool information about the css


Farhan Mar 04 2011

A very nice and use full article.

Jacob Gube Mar 04 2011

Google Translate of @hernan’s comment:

How nice it all the fonts …. you if you got that clear !!!!! good article!

@Tim: You are right. It’s been updated.

Laurent Mar 04 2011

This was really timely and helpful for me, especially the overview of the pseudo-classes.

One thing that might be helpful to explain, though (and which cost me about an hour of grief last night) is that if you want to use the selectors in a more specific context than just “any div” or “any p”, like

.my-class p { … }

you apparently have to use the _double-colon_. I spent a lot of time trying to figure out why my CSS wasn’t working, until I worked out that I needed to use

.my-class p::first-line { … }

Thanks, though. Good article.

Hugo Mejia Mar 04 2011

Great article. Concise and straight to the point. Looking forward for more…

gbsquared Mar 04 2011

Loved it. Looking forward to a little more. I really want to learn how to incorporate a lot more typography into my designs.

Shilpa Mar 04 2011

Thanks for sharing this Kayla. The psuedo classes are really cool.

Am a novice in typography…Are there any best practices on the line-height or character-spacing depending on the fonts and amount of text?

Kavya Hari Mar 05 2011

Hey, its one of the useful article to all the people.Kayla, you did a very good job and i would like to say thanks for written a great article on here.

Usman Mar 05 2011

Looking forward to learning more css tips in the upcoming articles

this is very clear and precise but really informational article. I will love to see much more of this kind in future

Hi, are you able to set the character height and width?

Stuart King Mar 06 2011


David Nemes Mar 06 2011

Very useful, thanks

Avangelist Mar 08 2011

One day there will be a simple method for using em in text. In 10yrs I have failed to successfully deploy it without ending up with at least a handful of cascading nightmares whether it is font sizes increasing down the stack or increasing. One nested list and it’s over.

Glenn Ferrell Mar 10 2011

Great series (already started 2nd part.) Didn’t know about the first letter / first line pseudo elements — really useful. (I was using :P )

daniel Mar 10 2011

Very useful article. As a programmer I always get confused by typography when it comes to doing th presentation side of websites.

Philipp Mar 11 2011

A great summary

Diogo Mar 15 2011

Excelent. Good job! :)

Great article, noticed you didn’t have the :focus pseudo-class for your links, any reason for this?

andrew Mar 22 2011

very nice indeed!

Thanks for the article.

Richard Mar 22 2011

In “Font Sizing”.

“Millimeters (mm), centimeters (cm), and inches (in) …. are not very suitable for screen-based measurements”
“Points (pt) and picas (pc) — while better than mm, cm and in ….”

Points _are_ inches. One point is 1/72 of an inch.

Inches on a screen are not the same as inches on paper. Screen inches have a different definition to paper inches. The division between absolute and relative lengths is a bit of nonsense that should have been discarded long ago.

sandra Mar 23 2011

excellent article. thank you very much.

ErrorGo Mar 23 2011

Very useful!

Thanks a bunch, this was great. I’m just starting out with html and css and the basics like this really help. The shown examples also helps to understand what the code is doing and why to use that code.

Very good stuff. New css very powerful. thanks for the compilation of new chips

Durgesh Aug 18 2011

Very useful tutorial. Thanks.

This comment section is closed. Please contact us if you have important new information about this post.