3-Column Layouts

Creating a three column layout with CSS: Part 1

Lets start with the XHTML. We start with a parent container, then include a header, content area and a footer, then add three columns to the content area. I will put "ipsum lorem" text in the examples that are linked from this page, but for the tutorial I will keep the content of our three columns, header and footer short.

<div id="parent">
     
  <div id="header">
		<p>HEADER</p>
  </div>
  
  <div id="contentarea"> 
    <div id="colA">
      <p>COLUMN A</p>
    </div>
    <div id="colB">  
      <p>COLUMN B</p>
    </div>
    <div id="colC">
      <p>COLUMN C</p>
    </div>
  </div>
  
  <div id="footer">
    <p>FOOTER</p>
  </div>
  
</div>

Just so we can see what is going on, let’s give them all borders and background colors, so we can tell the difference when we are doing this example. None of the following is part of what I want to teach you, but rather it makes the steps more legible and examples easier to understand.

#parent {
  border: 4px solid #ff0000;
  background-color: #222222;
}
#header  {
  border: 4px solid #ff9900;
  background-color: #444444;
  color #ffffff;
}
#contentarea {
  border: 4px solid #ffff00;
  background-color: #666666;
}  

#colA {
  border: 4px solid #66cc00;
  background-color: #888888;
}
#colB {
  border: 4px solid #3366ff;
  background-color: #aaaaaa;
}
#colC {
  border: 4px solid #663399;
  background-color: #cccccc;
}
#footer {
  border: 4px solid #ff33cc;
  background-color: #eeeeee;
}

<div>s are block level elements, so all this does is create blocks that go across the entire width of the page in normal flow. See our first example. Note: Adding borders to divs, as done above, affects their widths.

Introduction to creating columns

Normal flow is the way a document displays when there is no positioning or floating applied to it. The content will flow down the page, starting with the first element in your document and finishing with the last element in your document. The normal flow for a <div> is to take up the entire width of the page.

Instead of having the blocks of text one under the other, we want them to be next to each other, in "column" format. To create columns 2 things need to happen:

1) The sum of the widths of the three content divs, including the left and right borders, padding and margins of all three blocks of text, has to be less than the width of the container. We achieve this by setting the widths of the columns.

2) The blocks of text need can not appear in the normal flow, with divs above and below each other. Instead, then need to be "floated" next to each other.

Let’s add some CSS just as a preliminary example:

#colA, #colB, #colC {
  width: 30%;
  float: left;
}

I’ve set the width of the three columns to 30% instead of 33% because we have wide borders on the divs (remember: adding borders to divs as affects their widths). So the width is actually 30% + 4px left border + 4px right border. If you shrink the container width to below 240px, the right column will actually drop because the three columns width plus their borders is larger than the container because (30% * 240px + 8px total border) * 3 columns = 240px.

If you take a look at our second example, you’ll note that we have 3 columns, but the page is completely broken! Why? Because of float rules.

Floats: a primer

A float is a element that is laid out according to the normal flow, then taken out of the flow and shifted to the left (if floated left) or right (if floated right) as far as possible. When you float an inline element it becomes a block. Content can flow down the right side of a left-floated element and down the left side of a right-floated element, unless prohibited from doing so by the "clear" property, or because the width of a float is 100%. Floated elements will move to the left or right until their outer edge touches the containing block edge or the outer edge of another float. The top of a floated element will be at the same level as the float next to it, if there is enough room, or at the bottom of the preceding block if the element was originally inline. If there isn’t enough room on the current line for the floated box, it will move down, line by line, until a line has room for the float. (If two floats don’t appear to start on the same line, it is usually because the padding is different.)

Because a floated element is no longer in the normal flow of the document, non-positioned block boxes created before and after the float box flow vertically as if the float didn’t exist. If a parent or containing element only contains floats, the parent element will have no height, as if it were empty. This is what happened in our second example. Note that the #contentarea div (the yellow area) is only 8px high: the height of the top and bottom border.

A float can overlap other boxes in the normal flow. In our example, the three columns are taller than their parent and are overlapping the footer div.

One of the most important things to know about a float, and something that very few people know (and that I ask all potential job applicants) is that a floated element is at least as tall as the tallest floated element contained within it. So, let’s float the parent! but we need to give it a width, or it will shrink to be as narrow as possible. We need to get rid of the border, or our 100% will be 100% + 4px right border + 4px left border, which is more than 100%. Let’s make the background color different too, so it’s more visible. See the third example.

#contentarea { 
  float: left;
  width: 100%;
  border-width: 0;
  background-color: #ffff00;
}

There is a slight problem, which in the 100% width case wouldn’t really matter if we weren’t using such bright colors: note the top border of the footer is not showing. Why? Because the #contentarea has now been taken out of the normal flow. The text of the footer is appearing below the #contentarea because the content area width is 100%, so nothing can fit to the right of it, and therefore must be placed on the next line. Our page looks very different if we give the #contentarea a width of 50%: see the fourth example. The fourth example has similar issues to our second example, where the divs are going beyond the page.

Many instructors will advise to add a <br style="clear: both" /> equivalent here. I say we can do it much better! In the spirit of separating content from presentation, we can fix it via CSS without touching the HTML. Simply add the clear to the next element: the footer.

#footer { 
  clear: both;
}

Now, if you look at the fifth example, the footer falls completely below the content area, and we didn’t have to touch the HTML to add a <br>.

Now you know the basics of floats and the basics of using them to make a multiple column layout. In the rest of the series, I will show you how to make all three columns appear to have the same height, show you how to create columns differing widths, and point out some browser differences: how to avoid IE6 bugs and how to make various browsers render identically.

What we created was fairly ugly, but it worked. I will start from where we left off, but will remove the borders. I will continue to put "ipsum lorem" text in the examples that are linked from this page, but for the tutorial I will keep the content of our three columns, header and footer short. Notice the XHTML has NOT changed:

<div id="parent">
     
  <div id="header">
		<p>HEADER</p>
  </div>
  
  <div id="contentarea"> 
    <div id="colA">
      <p>COLUMN A</p>
    </div>
    <div id="colB">  
      <p>COLUMN B</p>
    </div>
    <div id="colC">
      <p>COLUMN C</p>
    </div>
  </div>
  
  <div id="footer">
    <p>FOOTER</p>
  </div>
  
</div>

We added colors to the divs so we could differentiate the columns from the footer from the header. I have changed the color of the #parent and #contentarea to make them more apparent for this tutorial:

#parent 
  background-color: #ff0000;
}
#header  {
  background-color: #444444;
}
#contentarea {
  background-color: #ffff00;
}  

#colA 
  background-color: #888888;
}
#colB {
  background-color: #aaaaaa;
}
#colC {
  background-color: #cccccc;
}
#footer {
  background-color: #eeeeee;
}

and finally, we added a few lines of CSS to make the columns work:

#colA, #colB, #colC {
  width: 30%;
  float: left;
}

#contentarea { 
  float: left;
  width: 100%;
}
#footer { 
  clear: both;
}

Recap of Part 1

What this bit of CSS did is gave the three columns widths that totaled less than the with of the parent element (the contentarea), floated the three "col" divs so they would appear as columns, and then floated the parent of the three columns so that the container of the columns would be at least as tall as the columns. Remember, because a floated element is no longer in the normal flow of the document, if a parent or containing element only contains floats, the parent element will have no height, as if it were empty. However, a floated element will always be at least as tall as it’s tallest floated child. So, by floating the #contentarea, the content area encompasses the three columns.

What we’re going to focus on in this tutorial:

Let’s take a look at the obvious issues in what we created. If you look at the current rendition of the columns, you will note the following:

  • The parent element (red) is showing thru above the content area, below the header.
  • The columns are all smushed to the left
  • The columns have no padding or margins
  • There is a lot of empty (yellow) space to the right, and jagged edges on the bottom.
  • The content, header, and footer are too tight: they also have no padding.

Making the page look nice

The first issue really has nothing to do with "column layout". It has to do with the default CSS of various browsers. Most browsers by default give margins to paragraph elements. If you are seeing the red #parent between the gray #header area and the yellow #contentarea, it is because the header paragraph has a bottom margin. That is why it is recommended to control your browser CSS defaults with a reset. Let’s control the header and footer and make them look header look nice.

#header {
	   padding: 20px;
}
#header p {
    font-style: italic;
    color: #ffffff;
    margin: 0;

}

#footer {
	   padding: 20px;
}
#footer p {
    text-align: center;
    margin: 0;

}

If you take a look at the page as it stands now, you’ll see it already looks better. So simple! Now lets address the columns.

Making the Columns look nice

What makes nice looking columns? Padding on all 4 sides. Padding between the columns. A middle columns being larger than the side columns. No ugly yellow. Columns being of equal height. hmmmm…. yup, we can do this.

To add padding to all 4 sides, we should simply be able to give padding to the parent container, but that won’t work! We declared the parent to be 100%; so adding padding would make to container wider than the header and footer. To make life easier for right now, let’s declare all widths in pixels instead of percentages.

#parent {
		width: 800px;
     margin: auto;
}
#contentarea {
		width: 760px;
		padding: 20px;
}

We declare an exact width for the parent of 800px. By declaring a margin of auto, the #parent will be centered.

We have added 20px of padding to the content area. That means 20px are added to the left and right (in addition to the top and bottom), so we have a total of 40px of padding between the left and right. 40px padding + 760px width = 800px.

We know we have 760px total for the three columns combined, so lets define their widths:

#colA {
	   width: 170px;
    margin-right: 40px;

}
#colB {

    width: 340px;
    margin-right: 40px;
}
#colC {
		width: 170px
}

If we do the math: 170px + 40px + 340px + 40px + 170px = 760px.
Note that we don’t need to add margin to the right of #col3, since we have the padding on the shell. Also, we use margin right instead of margin left because IE6 has a double-margin-float issue: when an item is floated to the left and and item has a margin-left that is greater than 0, IE6 doubles that width. Similarly, if an element is floated to the right, and the element has a margin-right that is greater than 0, IE6 will double that right margin. The page is actually looking really good in spite of the uneven columns, even in IE6. Let’s fix the uneven columns…

Creating Faux Columns using background images

We don’t want to declare a height on the columns since their heights will vary depending on the amount of content in the page. While there is no other way to ensure that the columns are the same height, we can make them appear to look like they are.

To create "faux columns", or appearance of columns with all the same height, we are going to add a background image to the #contentarea div that creates the appearance of columns for us.

#contentarea {
	   background-image: url(background.gif);
    background-repeat: repeat-y;
}

The image is simply a bar that contains a patch of color that is 210px wide on the left and on the right. Why 210px? The left padding is 20px. ColA is 170px wide. And, we want to cover half of the 40px margin between ColA and ColB with our column color: 20px +170px + 20px = 210px.

Background of faux columns

We’ve repeated this image vertically. To make the columns more interesting, I added a black 1px border. See the image above.

We need to remove the ugliness that we created to make this tutorial easier to follow, so we remove the background colors on colA, colB and colC.

#colA {
  background-color: transparent;
}
#colB {
  background-color: transparent;
}
#colC {
  background-color: transparent;
}

You can either overwrite the background color using the term "transparent" as above, or you can simply remove the CSS that we included earlier to create the background colors on those columns. Take a look at our final example. We have a presentable 3-column layout!

Practice on your own

You’ve learned the general techniques of doing a 3 columns layout. The same techniques can be used for 2-column or 4-columns layouts. Just remember that the columns, along with the added margins, need to be equal to or narrower than the parent holding those columns, accounting for any padding on that parent element.

If the total width of your columns is wider than the parent, your latter columns will drop below your first ones. If you have an item within a column that is wider than the column, like an image or too much padding, your column will drop. If a column drops, it is because your padding + margin + width of all your columns or their content was wider that the container, or because you forgot to float your columns.

The example in this tutorial uses specified widths. You are not required to use those exact widths. Try this tutorial using varying widths. Just remember to not exceed the width of the parent element, and, if you change number of columns or column widths, you will need to create a new "faux column" background to match your new layout.

This example also used padding and margins in a specific way to avoid IE6 bugs and common box model browser issues. I recommend using the padding on the parent and the margin on the columns in the opposite direction of the float to avoid any cross browser issues.

The layout we created may be all you need. But, what if they client says "I want the left nav on the right and the right nav on the left!"? Did you can change the order of your columns without touching your HTML? There is no re-ordering of the columns in a three column layout that isn’t possible.

In this tutorial, we look at the CSS required to change the order of your columns in your CSS without touching your HTML. I will continue to put "ipsum lorem" text in the examples that are linked from this page, but for the tutorial I will keep the content of our three columns, header and footer short. Notice the HTML has NOT changed:

<div id="parent">
     
  <div id="header">
		<p>HEADER</p>
  </div>
  
  <div id="contentarea"> 
    <div id="colA">
      <p>COLUMN A</p>
    </div>
    <div id="colB">  
      <p>COLUMN B</p>
    </div>
    <div id="colC">
      <p>COLUMN C</p>
    </div>
  </div>
  
  <div id="footer">
    <p>FOOTER</p>
  </div>
  
</div>

Listing 1: The HTML used in our examples

#parent {
    background-color: #ff0000;
    width: 800px;
    margin: auto;
}
#header  {
    background-color: #444444;
    padding: 20px;
}
#header p {
    font-style: italic;
    color: #ffffff;
    margin:0 ;
}

#contentarea { 
    float: left;
    width: 760px;
    padding: 20px;
    background-image: url(background.gif);
    background-repeat: repeat-y;
}
#colA, #colB, #colC {
    float: left;
}
#colA {
    width: 170px;
    margin-right: 40px;
}
#colB {
    width: 340px;
    margin-right: 40px;
}
#colC {
    width: 170px;
}
#footer {
    background-color: #eeeeee;
    clear: both;
    padding: 20px;
}
#footer p {
    text-align: center;
    margin: 0;
}

Listing 2: The CSS we are starting off with, based on Part 2 of this series in our embedded style sheet.

Recap of Part 1 and Part 2

In part 1, we floated the three "col" divs so they would appear as columns, and then floated the parent of the three columns so that the container of the columns would be at least as tall as the columns. Remember:

Because a floated element is no longer in the normal flow of the document, if a parent or containing element only contains floats, the parent element will have no height, as if it were empty. However, a floated element will always be at least as tall as it’s tallest floated child.

So, by floating the #contentarea, the content area encompasses the three columns. These three columns were all floated to the left. We declared a width on the parent element, added padding, then used simple addition to determine how wide to make each column and how wide to make the right margins on the first two columns.

Warning: Avoid the double float margin bug! When a margin is applied to a floated box on the same side as the direction the box is floated and the floated box is the first one inside its containing box, the margin is doubled in IE6 and lower. In other words, if a element is floated left, and you have a left margin of 20px on that element, that element will appear to have a left margin of 40px in older versions of IE.

In part 2, we used basic math to take our floated columns from part 1 and turn it into a better looking fixed 3-column layout, including margins and padding. To make the columns appear to have the same height we created "faux columns" by adding a background image to the parent of the three columns. We also added a bit of padding to the header and footer to make them look better. But that’s pretty much it…

Changing the left to right and right to left

The best part about separating the 3 layers of content, presentation and behavior, separating XHTML, CSS and JavaScript, is that you can do major layout changes without touching the original code. We are going to change the order of the columns from Column A-B-C to Columns CBA. To do this we float right instead of left. We also have to change the margins from right to left to avoid the IE double float margin bug.

#colA, #colB, #colC {
    float: right;
}
#colA {
    width: 170px;
    margin-left: 40px;
}
#colB {
    width: 340px;
    margin-left: 40px;
}
#colC {
    width: 170px;
}

Listing 4: CSS rules in an embedded style sheet changing column visual order to C-B-A

That’s all there was to it in this example. Had our #colA and #colC not have been of the same widths, we might have to change either their widths or the background image.

Note that we could have floated column C to the left instead, and then we can omit the left margin on column B.

Remember: class names and ids should be based on function rather than styling. If we had named the columns "left column", "middle column" and "right column", this tutorial would be really confusing. CSS may change your layout, but it won’t change your content. When choosing class and id names, think of the purpose of the styling rather than the styling itself. Choose names that make the funtion of the element clear. When creating a new design, you’ll be able to easily identify the purpose of the styling.

Changing it around again…

Just for yucks-and-giggles, let’s move the columns around again – Columns B-C-A.

#colA {
    float: right;
    width: 170px;
    margin-left: 40px;
}
#colB {
    float: left;
    width: 340px;
}
#colC {
    float: right;
    width: 170px;
}

Listing 5: CSS rules in an embedded style sheet changing column visual order to B-C-A

We floated Column A to the right. Because it’s floated right and we will be floating another element in that direction, we gave it a left margin. We wanted Column B to be on the left, so we float it left. Because no other elements are going to be floated left, there is no need to add a right margin. Then we floated column C to the right. We could have floated column C to the left, and it would have still been in the middle. Had we done so, however, we would have had to put a left margin on column B, and we could have omitted the left margin on column A.

Are there any issues with the redesign? Yes. Column B is the widest, but is now on the left. The background image was created for the middle being the widest. We can either change the widths or change the background. You’ll want to change the background image! You don’t want a wide navigation column and a narrow content columns.

Background of faux columns

Listing 6: Background image with largest column on left

 #contentarea { 
    background-image: url(background2.gif);
}

Listing 7: CSS rule to change the background image (you can also overwrite your image name instead)

You’ll want to create a background image that has the largest column first. You can overwrite your original background image file name. But, since this is a tutorial, I have given the image a new name, and therefore had to update the CSS. Now it looks right.

What have we learned?

By touching only the CSS, and not touching the (X)HTML, we were able to completely change the layout order. Pretty cool. Just remember, in creating 3-column (or more or less), calculate your margins, paddings and widths. If you go over the width of the container, your last column will drop. If you include elements in a column that are wider than the column, unless you declare the overflow property, will increase the width of the column and may cause the column to drop. And, again, if your margins look off in IE6 (or lower), it could be the double margin bug.

Only include margins when necessary. If you omit the margin when not necessary, you get a little bit of leeway should you have an element that increases the size of one of your columns.

Will floating alone take care of everything? No!

What are we missing?

With 3 columns, there are six possible column orders. We can get 4 of the layouts with simple floating and positive margins, but when the first column in content order needs to be in the middle, we have to go into new territory.

A B C – A – float: left; B – float: left; C – float either way
A C B – A – float: left; B – float: right; C – float either way
B C A – A – float: right; B – float: left; C – float either way
C B A – A – float: right; B – float: right; C – float either way

However, there are no combinations that allow us to create the following layouts using our simple CSS.
B A C
C A B

For these combinations, because of the first column in the (X)HTML being in the middle, it would seem that you couldn’t simply float the columns. You actually can. The trick is negative margins:

#colA {
    float:left;
    margin-left:380px;
    width:170px;

}
#colB {
    float:left;
    margin-left:-550px;
    width:340px;
}
#colC { 
    float:right;
    width:170px;
}
 

Listing 8: CSS rules in an embedded style sheet changing column visual order to B-A-C

With negative margins, we are able to place the first column in the middle. We float the first column to the left, but we give it a left margin to enable us to put Column B on the left. Column B is 340px wide. We also want to ensure that we include the 40px margin between Column B and Column A: 340px + 40px = 380px.

This is where the double float margin bug comes into play. Because we are floating left and providing a margin left on the first floated element within a floated parent, IE6 doubles the left margin provided. So we need to include IE6 (and older) conditional CSS in which we halve the left margin:

#colA {
    margin-left: 190px;

}

Listing 9: CSS rules for IE6 and less for changing column visual order to B-A-C

We then want to push Column B all the way to the left (well, inside the parent’s padding). If we simply floated it with no margin, the column would land at 550px from the left padding: the width of Column A (170px) and the left margin on Column A (340px): 170px + 340px = 550px. To put the column in the correct location, we give Column B a negative margin: margin-left: -550px;. The CSS looks weird. It is. But, mathematically, it works.

Note that again with Column C, you can float either left or right, but if you float left you need to include a left margin of 40px, so floating right is simpler.

Practice on your own

You’ve learned the general techniques of rearranging columns in a 3 column layout. I purposely omitted 2 columns combinations. On your own, try creating the following:

  1. A C B
  2. C A B

CSS Reset

Resetting browser default CSS

Whenever I start a new site and begin a new CSS file or CSS file set for the site, my first step is to include CSS to reset the browser CSS defaults.

Different browsers have slightly different default rendering. The default values for margin, padding and line-height differ between browsers. Removing the inconsistent default styling for elements in various browsers creates an equal starting point and allows you to explicitly set your own default settings that are equal in (almost) all browsers. By starting with an equal playing (or presentation) field, your CSS will not only look similar in all browsers, but your CSS file size will be smaller, and the number of aspirin you need to take to complete your site will be reduced.

Code

Here is the code I generally use. I’ll explain it below:

/* CSS BROWSER RESET */

body, div, h1, h2, h3, h4, h5, h6, p, dl, dt, dd, ul, ol, li, 
pre, form, fieldset, legend, input, textarea, label,
blockquote, table, th, td {
		margin: 0;
		padding: 0;
		background-repeat: no-repeat; 
		font-family: Verdana, Arial, Helvetica, sans-serif; 
		font-size: 100%; 
		line-height: 1.4; 
		color: #333333; 
	}
a, span {
		background-repeat: no-repeat; 
		outline: none;	
}

table {
		border-collapse: collapse;
		border-spacing: 0;
	}

fieldset, img, abbr, acronym {
		border: none;
		text-decoration: none; 
	}

ol, ul {
		list-style: none;
	}
caption, th {
		text-align: left;
		font-weight: normal;
	}

q:before, q:after {
		content: '';
	}

input, textarea, select {
		font-family: inherit;
		font-size:inherit;
		font-weight:inherit;
	}


 /* declare your site defaults here */

In your conditionally commented CSS file for IE7 and less include the following:

input, textarea, select {
		font-size:99%;
	}

CSS explained

While you may not use all the elements listed, and you may want your defaults to be slightly different, the above CSS is a good starting point. You might as well include all these elements, because you never know if someone else coding the site, or a future developer, may use those elements.

The first call sets the margin and padding of all elements to none. You won’t have to declare margin and padding of 0 again in your CSS. I have seen style sheets with ‘margin: 0′ included over 100 times. By including this default CSS, you only have to declare margins when you are overwriting the new zero default. Also, you don’t have to remember to explicitly set the body padding and margins.

Different browsers also display h1-h6 differently. This CSS nullifies the browser default settings and makes them look like the rest of your code. This way you decide how you want to display your headings. Also, by declaring a font-size in percentages, we resolve the IE ems rendering issues.

There are some settings in the code above that are redundant or irrelevant and will have no impact, such as setting margins on inline elements. CSS does not penalize you for including properties that are not used. I include all the elements in the first line, even though some of the properties are not used on some of the elements.

The default value for background images is to have them repeat on both the X and Y axis. Generally, you don’t want background images to repeat. The CSS above sets the background-repeat to no-repeat.

Just remember to AVOID use the background shortcut. If you omit one of the elements of the shorthand (background-color,
background-image,
background-repeat,
background-attachment,
background-position) you may inadvertently reset one of the properties to the default.

The call includes several optional/changeable items. Feel free to reset the font-family, color and line-height to your own preferences.

With font-family, include default fonts in the initial CSS browser reset. By declaring the fonts in this way, you will save a lot of characters by not having to declare default fonts elsewhere in your CSS. For example, if you declare your <h1> on your contacts page to have a unique font, you simply have to write something similar to:

#contact h1 { font-family: Hacknslash;} 

If the user doesn’t have the "Hacknslash" font, then it will default to Verdana, Arial, Helvetica, sans-serif, since you declared that in your brower reset CSS.

I chose the grey of #333333 instead of #000000, because black on white can be hard on the eyes. This dark grey is less harsh. You can use whatever color your design requires.

Line height is also up to you. You’ll note that there is no measurement type such as em, px, pt or % included. You can use these measurements. Omitting the measurement sets a number that will be multiplied with the current font-size to set the distance between the lines, similar to declaring em or %.

Since links, spans, code and other in-line elements have no default margin and padding and inherit, I declare them seperately to not overburden the browser rendering engine. I’ve declared two elements in this case as I use a lot of background images in my links and spans and want to ensure that those background images don’t repeat. The outline: none; on the links removes the box you may see around links when the mouse is down.

Note that you should not use the global selector, *, because the browser may overwrite default styling that you want to keep, such as padding on buttons. Also, when the global selector is used, the browser than has to apply the style to every element, which is a heavy load for the browser.

Defaults bullets are removed from ordered and unordered lists. Bullets are placed in different locations in different browsers: Firefox vertically aligns the bullet to text bottom and Internet Explorer vertically aligns the bullet to text top. I like to not only control my bullets, but generally my <li>s are inline, have background images instead of bullets, or are otherwise styled.

The caption and table header declarations are included since browsers tend to center them, and tend to bold table headers. The quote declaration is included since Firefox, Opera and other compliant browsers add quotes to <q>, while Internet Explorer, up to IE7, doesn’t even understand the :before and :after pseudo-classes. (This is resolved in IE8).

Most of the rest of the CSS is self explanatory except perhaps the IE conditional comments portion. Browsers are notorious for rendering forms differently: the input, textarea, select font-size declaration tells IE7 and earlier to not enlarge fonts that are in form elements.

Remember to include your form elements in block level elements. For example, put <textarea> in a <p> element so that it inherits font-family correctly in Opera.

The last line, "declare your site defaults here", is a good spot to declare the other default fonts and colors for your site. If all your h1s are going to be a different color and font, then start with your general, non-classed declarations. Remember to include this Browser Reset CSS at the top of your CSS. In this way, you can use the cascade to declare your defaults without requiring classes. Otherwise, you would have to include additional specificity for things that really should be generally declared.

Other browser reset arguments

There is an argument to remove ALL the defaults, such as bolding of the <strong> element, italicizing of the <em> element, monospacing of the <code> element, etc. The argument is that you should start from scratch, and build up all your own CSS. Below are some additional statements you can consider including in your CSS browser reset:

address, caption, cite, code, dfn, em, strong, th, var { 
	    font-style:normal; 
	    font-weight:normal; 
	} 
	h1, h2, h3, h4, h5, h6 { 
	    font-weight:normal; 
	} 

sup {
		vertical-align: text-top;
	}

sub {
		vertical-align: text-bottom;
	}