Centering a site

Works fine in all modern browsers. Creates a mess in Netscape 4, though.

For another method, see Web Page Design for Designers.

Update: Explorer 6 turns out to support margin: auto in Strict Mode, though not in Quirks Mode.
Combined with the Joe Gillespie's better way to do it (see link above) this means this page already has to be rewritten.

Recently I came upon one of those silly site designs that consist of a fixed 800x600 block that should be centered in the browser window. I decided to solve this old, old problem once and for all.

We used to center such a site by using a frameset. Fortunately, CSS makes this particular brand of framesets obsolete. Nonetheless, pure CSS is not enough, we need one table (but no more).

See the centering example.

Positioning the parts

The main problem with a fixed 800x600 design that should be centered is that it is fixed. No smooth, liquid design to fill out the entire browser window. Nonetheless this fixedness has one advantage: we can use fixed measurements ourselves, too.

We can position the various parts of the site (navigation, content area, etc.) absolutely. The dimensions of the site parts won't change anyway, so we can use pixel precise layout and absolute positioning.

HTML:

<div class="left">
	Left content
</div>
<div class="top">
	Top content
</div>
<div class="main">
	Main content
</div>

CSS:

div.left {
	position: absolute;
	top: 0px;
	left: 0px;
	width: 200px;
	height: 432px;
}

div.top {
	position: absolute;
	top: 0px;
	left: 200px;
	width: 580px;
	height: 150px;
}

div.main {
	position: absolute;
	top: 150px;
	left: 200px;
	width: 580px;
	height: 282px;
}

You should define everything: top, left, width and height. Once you've done that the site has the correct layout. It is now fixed in the upper left corner of the window, because the coordinates of our absolutely positioned layers are calculated relative to this upper left corner of the window.

That's no problem. We only have to move this entire construct to the center, and the problem has been solved.

See Example 1.

Container

For ease of positioning, we put all these divs in one container div.

<div class="container">
	<div class="left">
		Top content
	</div>
	etc.
</div>

We give this container position: relative. This makes sure that the three absolutely positioned layers are now positioned relative to the container div. This allows us to move the container div across the screen. The absolutely positioned layers will faithfully follow.

We also give the container a margin: 0 auto. This takes care of its horizontal centering in all browsers but Explorer Windows.

Finally, we must give the container a width and a height, too. It contains only absolutely positioned elements, and no elements in the 'normal flow' of the page.

Therefore, 'natively' its width and height retain their natural values: 100% and 0. When we center the container div these dimensions could lead to serious problems, since the browsers would center a 100% x 0 block.

Solution: give the container the correct width and height. Then the browsers will center a correctly dimensioned block and it will look fine.

div.container {
	position: relative;
	margin: 0 auto;
	width: 780px;
	height: 432px;
}

See Example 2.

Now the site is centered horizontally in all browsers but Explorer Windows.

Vertical centering

Unfortunately, vertical centering is a notorious weak spot of CSS. Vertical centering is only possible for content of TD's. Don't ask me why, I disagree strongly, but the problem is there and should be solved.

So we hand the vertical centering problem to a table. Add table:

<table border=0>
	<tr>
		<td>
			<div class="container">
				<div class="left">
					Top content
				</div>
				etc.
			</div>
		</td>
	</tr>
</table>

Give the table a 100% width and height. Then add vertical-align: middle to the td. This is the only way of centering content vertically in CSS.

table {
	width: 100%;
	height: 100%;
}

td {
	vertical-align: middle;
}

See Example 3.

Explorer Windows

The site is now centered horizontally and vertically, except in Explorer Windows, where it is only centered vertically.

As we know, Explorer Windows doesn't support margin: auto, so it doesn't center the site horizontally yet. Fortunately it allows us to center blocks by the (incorrect) use of text-align: center.

So we add that declaration to the td, and overrule it again in the container div. If we didn't overrule it, all content would be centered, too, and that's not what we want.

td {
	vertical-align: middle;
	text-align: center;
}

div.container {
	position: relative;
	margin: 0 auto;
	width: 780px;
	height: 432px;
	text-align: left;
}

Problem solved. The 800x600 site is centered horizontally and vertically.

See the centered page.