Page Layout

So far, all your pages have been laid out with one column stretching all the way across the screen. In these notes, you will learn how to make a more complicated layout with multiple columns.

While tables were originally supposed to be used for tabular data only, it took developers a grand total of five milliseconds to realize that they could be used to drive page layout. Since stylesheets didn’t exist at the time, this was a perfectly reasonable thing to do. In fact, because stylesheet support is not perfect in any browser, there have always been reasons to use tables to lay out a page. However, with the advent of HTML5 and more sophisticated style sheets, you should no longer need to use tables to do layout.

Creating a Three-column Layout

Take a look at this sample page. This is a typical three-column layout, with each column having a fixed width.

Before going into how the CSS makes this happen, you need to learn about some new HTML5 elements that you should use when writing your pages.

New HTML5 Elements

If you look at the sample page, you will see that it has a header at the top, a site navigation area at the left, an article about tourist spots that has two sections, an article about the weather, and the footer with the copyright notice.

HTML5 introduces new elements for each of these parts of a web page: <header>, <nav>, <article>, <section>, and <footer>. You use them exactly as their names imply. Here is the general layout (very abbreviated) for the page. The <nav> is the left column, the <div id="content"> is the center column, and <div id="feature"> is the right column.

<body>
   <div id="container">
      <header>
         Seoul Tourist News
      </header>
      <nav>
         Main Page and links
      </nav>
      <div id="content">
         <article>
            <section>Kwang-hwa-mun</section>
            <section>Myeong-Dong</section>
         </article>
      <div id="feature">
         <article>
            <section>Weather forecast</section>
         </article>
      </div>
      <footer>&#169; 2010</footer>
   </div> <!-- end of container -->
</body>

The extra <div id="container"> is there so that the CSS will work properly.

The CSS

Let’s start with the CSS that establishes the width of the entire page.

header, footer, section, article, nav {
	display: block;
}

* {
	margin: 0;
	padding: 0;
}

#container {
	width: 800px;
	margin: 0 auto 0 auto;
}

The new HTML5 elements are not recognized by older browsers; they will not know how to display them. The first three lines of the CSS tell the browser to display them as block-level elements (they will all start a new line).

The * means “all elements.” This means that none of the paragraphs, headings, etc. will have any margins or paddings unless you add them specifically. The <div id="container"> has a width of 800 pixels; chosen because most screens will accommodate that width nicely. The margin has a top and bottom of 0 pixels, and the left and right are set to auto. This will center the page horizontally within the browser window.

Now you can set up the three columns.

nav {
    width: 150px;
    float: left;
}

#content {
    width: 450px;
    float: left;
}
 
#feature {
    width: 196px;
    padding-left: 4px;
    float: left;
}

The total width of the columns must add up to the same width as the container. Each of the columns has a float: left property; this causes the columns to line up from left to right. Note especially the #feature specification. In the CSS box model, the width refers to the width of the content area, not the width of the entire box. The toal width of the box, in fact, is the width of the content plus the horizontal padding plus the horizontal margin. In this case, the padding-left serves to leave visual space between the middle and right columns.

That solves the main layout. Now it’s time to style the <header> and <footer>.

header {
    text-align: center;
}

header h1 {
    margin-top: 0.5em;
    margin-bottom: 0;
}

header p {
    font-size: small;
    font-style: italic;
    background-color: #ffffcc;
    padding: 1em 0;
    margin-top: 0
}

footer {
    clear: both;
    font-size: small;
    text-align: center;
}

Inside the <header>, the <h1> has no bottom margin, and the <p> has no top margin. That puts them (visually) closer together.

You may also have noticed that the padding: 1em 0; has only two values instead of four. This is a shortcut. If you specify only one value for padding or margin, it applies to all four sides. If you specify two values, the first value applies to top and botom and the second value to left and right. If you specify three values, the first value applies to the top, the second to left and right, and the third to bottom. Of course, if you specify four values, you completely specify all four sides of the padding (or margin).

The footer needs to clear: both so that it will appear below the floated columns.

nav ul {
	list-style-type: none;
}

p {
    margin: 0.5em 0;
}

table { border: 1px solid black; }
th, td {
    border: 1px solid black;
    padding: 0.5em;
}

Finally, the navigation area has its list-style-type: none; so that bullets don’t show up. The <p> gets a one-half em margin on the top and bottom, and the table elements get border and padding.

Other Layouts

This layout works, but it gets really ugly when you make the window narrower than 800 pixels; you have to scroll left and right to see the whole page. What you may want, instead, is a liquid layout, where the left and right columns have a fixed width, and the center (content) layer contracts and expands as the browser windows shrinks and grows. Also, you want a layout that will work with older browsers that do not respect web standards as well as with the most modern browsers.

Rather than re-inventing the wheel (which usually ends up with re-inventing the flat tire), I will point you to these articles. Please, please, do not use these layouts without first reading about them and making your best effort to understand how and why they work!