A reader recently asked how to create
a centered page layout using CSS. The effect the reader is looking for is similar
to the layout achieved by centering an 800-pixel-wide table on a 1024-pixel-wide
page. It’s a widely used page layout that traditionally relies on nested tables
to achieve the effect, so it’s not surprising that the reader is looking for a way
to replicate the effect with CSS.

The basic technique for creating a centered
page layout in CSS is relatively simple, but it’s not obvious. Let’s see what it
takes to convert this old standby from tables-based layout to CSS.

A centered layout, the old way

First, for the sake of comparison, let’s
look at an example of a page layout based on a centered table. The following code
produces the example shown in Figure A.

<table width="80%"  border="0" align="center" cellpadding="0"
        <td colspan="2"><h2 align="center">Header</h2></td>
        <td width="150px" valign="top"><h4>Navigation</h4>
                <li>Let me not to the marriage of true minds</li>
                <li>Admit impediments; love is not love</li>
                <li>Which alters when it alteration finds</li>
        <td valign="top"><p>Main Content -- Love's not
time's fool...</p>
        <td colspan="2"><hr />
            <p>Footer text -- Admit impediments...</p>

The <table> tag includes attributes
that define the width as 80 percent of the page width and centers the table on the
page. An empty paragraph preceding the table creates some vertical space between
the top of the page and the top of the table. Another empty paragraph following
the table does the same at the bottom of the page. The table itself contains two
columns and three rows of cells. The cells in the top and bottom rows are merged
to create header and footer panels, while the cells of the middle row create two
columns—one for the main content and another for a navigation sidebar.

This is a very simple example of a technique
that has been in widespread use for years. In real-world applications, the main
table would typically contain other nested tables to create a more complex layout,
but the added complexity doesn’t change the basic technique.

Converting the layout to CSS

To convert this traditional table-based
layout to CSS, you simply replace the table and the table cells with divs. One div
replaces the table itself, and other divs replace the individual table cells that
define the major layout elements, such as the header, footer, nav sidebar, and main
content. The divs are each identified with a unique id that can be referenced with a CSS selector to create styling that applies
specifically to the div with that id. The div that replaces the table is labeled
id=outer, and the other divs are identified
by their respective function.

Here’s the revised XHTML code with divs
instead of a table:

<div id="outer">
    <div id="header">
    <div id="nav">
            <li>Let me not to the marriage of true minds</li>
            <li>Admit impediments; love is not love</li>
            <li>Which alters when it alteration finds</li>
    <div id="main">
        <p>Main Content -- Love's not time's fool...</p>
    <div id="footer">
        <p>Footer text -- Admit impediments...</p>

Notice that all the presentation formatting
that was previously included in the <table> and <td>
tags has been removed. The empty paragraphs before and after the table are
gone as well. CSS styling will handle all the formatting and spacing.

Here’s the CSS code that styles the page
as a centered layout similar to the tables-based page above:

body {
    background-color: #999999;
    font-family:Verdana, Arial, Helvetica, sans-serif;
div#outer {
    width: 80%;
    margin-top: 50px;
    margin-bottom: 50px;
    margin-left: auto;
    margin-right: auto;
    padding: 0px;
    border: thin solid #000000;
div#header {
    padding: 15px;
    margin: 0px;
    text-align: center;
div#nav {
    width: 25%;
    padding: 10px;
    margin-top: 1px;
    float: left;
div#main {
    margin-left: 30%;
    margin-top: 1px;
    padding: 10px;
div#footer {
    padding: 15px;
    margin: 0px;
    border-top: thin solid #000000;

Figure B
shows the result—a centered page layout executed with CSS.

Analyze the CSS code

The body style is unchanged from the
table-based design. It just sets the background color and default text font and

The div#outer style is the one that holds the key to this technique. This
is the styling for the div that creates the centered box which serves as the container
for the rest of the page content–the div that replaces the table. The width: 80% rule sets the width of the div,
just as the corresponding attribute of the table tag set the width of the table.
Similarly, the background-color:#FFFFFF rule creates a white background for the div like
the bgcolor=”#FFFFFF” attribute
did for the table. The margin-top: 50px
and margin-bottom: 50px rules replace
the spacer paragraphs with top and bottom margins for the div itself.

The key to this technique is proper centering
of the outer div. The challenge is that
there is no align=”center” attribute
for a div like there is for a table. You could use text-align: center for the div’s parent element (in this case, the <body>
tag) to center the outer div. However,
although most browsers will use that alignment for block-level elements, such as
divs, in addition to text, it’s arguably a misuse of the text-align attribute and
leads to complications as you create additional styles to reset normal text alignment
back to left.

The proper way to center a block-level element with CSS is to set
margin-left: auto and margin-right: auto. This instructs the browser
to automatically calculate equal margins for both sides, thus centering the div.
The border: thin solid #000000 rule adds
a border around the outer div, just because it’s easy to add with CSS but difficult
to accomplish with tables. The rest of the CSS code styles the divs for the header,
footer, nav, and main content.

The div#header and div#footer styles set margins and padding for those divs. In addition, div#header
includes the text-align: center rule to
center the header text, and div#footer
includes the border-top: thin solid #000000
rule to create a border along the top edge of the div to replace the horizontal
rule above the footer in the table-based layout.

The div#nav and div#main styles
create the two columns in the middle of the centered box. In the div#nav style, the float: left rule pushes the div to the left side of its parent element
(the outer div), and the width: 25% rule
sets the div’s width to 25 percent of the parent element. With the nav div floated
to the left and limited to a set width, it leaves room for the main div to move
up to the right of the nav div, thus creating the two-column effect. The div#main style includes the margin-left: 30% rule to keep the main text
aligned in a neat column instead of spreading out below the nav column. The main
div’s left margin is set to a value slightly larger than the width of the nav div.
I cover the technique for creating columns with floats in more detail in my column
“Use CSS
floats to create a three-column page layout.”