There are a lot of articles out there about typography on the web. I wanted to explain my method of controlling font sizes and margins in CSS.

I love Dan Mall’s Soft Serve Technique, but then you have to make a special case for IE6. (Hopefully it won’t be too much longer that we have to worry about IE6).

Getting a Usable Base Font Size

Ok, so to start, I like setting the font size of the body to 62.5%. I used to take Dan Cederholm’s approach of setting the font size to small, but I finally realized that it did not give me a nice base font size to play with.

So by setting the font size of the body to 62.5%, we get a base font size of 10px. This gives us a nice round number to work with. Thus, 1em now equals 10px. 10px is way too small to be the font size of the content though. Thus, I just set the font size of the outter-most container to 1.2em. Since we had a base size of 10px, our font size in the container becomes 12px.

Heading Font Sizes

The next thing I like to do is to set the font sizes of all of the headings, h1-h6. A good set of values for headings is:

  • h1: 22px
  • h2: 20px
  • h3: 18px
  • h4: 16px
  • h5: 14px
  • h6: 12px

Again, these are just values that I am suggesting, you could definitely choose whatever you want.

To get these font sizes, we just need to do some simple math.


Let’s use an h3 as an example. We take the size that we want the heading to be, 18px, and divide it by the container font size, 12px. So, 18/12 = 1.5. Then, we set the font size to either 1.5em or 150%. I personally like working with ems, although I used to prefer percentages.

So again, font size we want to achieve / font size of the container. Use this to compute the rest of your heading font sizes, and then you will have nice pixel values to work with.

Attacking the Margins

So obviously you want to avoid letting the browser control how your elements will be spaced, so let’s work on setting the margins on these elements too.

Remove the Default Margins

The first thing I do in a stylesheet is zero out the margins and paddings:

html, body, div, h1, h2, h3, h4, h5, h6, ul, ol, dl, li, dt, dd, p, blockquote, pre, form, th, td {
 margin: 0;
 padding: 0;

Next, I set a bottom margin of 1em on p, ul, ol, dl, blockquote:

p, ul, ol, dl, blockquote { margin-bottom: 1em; } 

Then, to get an equal amount of margin on the bottom of the headings, we just need to do more simple math. We can’t just set the bottom margin to 1em because our font size on these elements are bigger than the rest of the content.


So let’s use the h3 as an example again. This time, we take the font size of the container, 12px, and diving it by the size of the heading, 18px. 12/18 = 0.667. So then, our h3 would look like this:

h3 {
 font-size: 1.5em;
 margin-bottom: 0.667em;

So again, font size of the container / font size of the element. If you do this for all elements, you will have an equal margin between all elements. I made a page showing elements with equal margins.

I used to think this was best, but I have since realized that I like having the headings closer to the text that is following. So I divide the bottom margin on the headings by 4. Thus, we get a quarter of the margin above the heading, below it.

In my opinion, the example page with custom margins looks much better.

Anyone else have other methods?