Published on October 15th 2007.
Modified on July 26th 2010.
Many people still use tables to hold their page content but this really isn't how things should be done. The table tag is used to hold tabular data. Anything that can be represented in columns and rows belongs in a table. Tables aren't used to layout content.
div tagIf used correctly the div tag can save you a lot of hassle. Compared to coding tables, the div tag is more lightweight and versatile. Instead of dealing with colspan and rowspan and tds and trs, we now have just one tag div. Not only that - divs can be manipulated many ways with CSS, as you are about to see, to produce a variety of different layouts.
Here I will show you how to float two columns next to each other. For a two column equalising layout (i.e., a layout whose columns are all as tall as the highest column), see below.
/* The parent container */
#parentContainer {
background-color:#CCCCCC;
width:600px;
font-size:130%;
text-align:center;
}
/* The header */
#header {
height:80px;
background-color:#0066CC;
width:600px;
margin-bottom:4px;
}
/* The inner-container */
#innerContainer {
width:600px;
height:100%;
overflow:auto;
background-color:#CCCCCC;
}
/* Column one */
#col1 {
width:160px;
height:40px;
overflow:auto;
margin:0 5px 0 0;
float:left;
background-color:#0066CC;
}
/* Column two */
#col2 {
width:435px;
height:40px;
overflow:auto;
float:left;
background-color:#0066CC;
}
/* The footer */
#footer {
height:20px;
background-color:#0066CC;
width:600px;
margin-top:4px;
}
<div id="parentContainer"> <div id="header"></div> <div id="innerContainer"> <div id="col1"></div> <div id="col2"></div> </div> <div id="footer"></div> </div>
We are creating two columns to be floated side by side and placing them in a div called innerContainer to separate them from the header and footer. The whole layout is then placed in a div called parentContainer. The parent doesn't have a specific width, as it doesn't need one, but innerContainer does. innerContainer has a width which takes into consideration the widths of our two columns (160px + 435px) and also any margins or padding or borders applied to the inside elements. Well, we haven't used any padding or borders, but we have used a right margin. So the final sum of parentContainer's width is 160px + 435px + 5px = 600px.
As you can see, our two columns are nested side by side.
When you float objects side-by-side inside a container, if the widths of the floated objects are greater than the width of the container, your layout may not render as desired. If your floated items don't have the necessary room, they may end up stacked on top of each other. This is easily rectified by increasing the width of the container which holds them.
So make sure, when using definite widths for containers which contain floats, that your numbers add up...and that the width of your container(s) take into consideration any margins and padding applied to inner elements.
To centre align two columns we must apply margin:0 auto to the container which holds them. This will create equal margins on both sides, thus centring the columns inside the container.
Let's see how this is done.
/* The parent container */
#parentContainer {
background-color:#CCCCCC;
width:600px;
font-size:130%;
text-align:center;
margin:0 auto;
}
/* The header */
#header {
height:80px;
background-color:#0066CC;
width:600px;
margin-bottom:4px;
}
/* The inner-container */
#innerContainer {
width:600px;
height:100%;
overflow:auto;
background-color:#CCCCCC;
}
/* Column one */
#col1 {
width:160px;
height:40px;
overflow:auto;
margin:0 5px 0 0;
float:left;
background-color:#0066CC;
}
/* Column two */
#col2 {
width:435px;
height:40px;
overflow:auto;
float:left;
background-color:#0066CC;
}
/* The footer */
#footer {
height:20px;
background-color:#0066CC;
width:600px;
margin-top:4px;
}
<div id="parentContainer"> <div id="header"></div> <div id="innerContainer"> <div id="col1"></div> <div id="col2"></div> </div> <div id="footer"></div> </div>
This layout is practically identical to the layout above, the only difference is the margin:0 auto applied to our parentContainer. As you can see, when you want to centre floated items, all you need to do is to wrap them in a container, which is centre aligned using margin:0 auto. Simple as that!
When you float objects side-by-side inside a container, if the widths of the floated objects are greater than the width of the container, your layout may not render as desired. If your floated items don't have the necessary room, they may end up stacked on top of each other. This is easily rectified by increasing the width of the container which holds them.
So make sure, when using definite widths for containers which contain floats, that your numbers add up...and that the width of your container(s) take into consideration any margins and padding applied to inner elements.
Ever wanted to have your columns all the same height, without using definite measurements? So, let me get this straight...it is possible to have my short navigation panel stretch to be the same height as my incredibly long main content...I hear you cry? Yes it is. And here is how you do it.
CSS three has a whole stack of properties which really help when creating multi-column layouts. Unfortunately these aren't widely supported so we have to look elsewhere.
This is the most common technique for creating equalising columns and involves a little image trickery! It works by applying a repeating background image to our container, to create the illusion that the short column is as long as the image, when, in fact, it isn't. If you're not with me, here's an example.
Say you have a two-column website, navigation on the left and main content on the right. Your navigation is mostly shorter than your main content (though not always) but you would like both columns to be the same height. To get round this you would apply a background image with the same width as the navigation to the container which holds both columns. You would then position it behind the navigation and set it to repeat-y, so it repeats vertically.
/* The parent container */
#parentContainer {
background-color:#CCCCCC;
width:600px;
font-size:130%;
}
/* The header */
#header {
width:600px;
height:80px;
background-color:#0066CC;
margin-bottom:4px;
}
/* The inner-container */
#innerContainer {
width:600px;
overflow:auto; /* You need this to stop the float from leaking out of innerContainer */
background:url(../images/nate_drake.jpg) repeat-y;
}
/* The navigation */
#nav {
margin:0;
padding:0;
list-style-type:none;
width:200px;
margin:0 5px 0 0;
float:left;
}
/* The navigation elements */
#nav li {
background-color:#666666;
color:#ffffff;
margin-bottom:6px;
padding:3px;
}
/* Main */
#main {
width:395px;
min-height:400px; /* You need this if you don't want your main content to be shorter than your navigation */
float:left;
background-color:#66F;
}
/* The footer */
#footer {
width:600px;
height:20px;
background-color:#0066CC;
margin-top:4px;
}
<div id="parentContainer">
<div id="header"></div>
<div id="innerContainer">
<ul id="nav">
<li>Navigation</li>
<li>Navigation</li>
<li>Navigation</li>
<li>Navigation</li>
<li>Navigation</li>
<li>Navigation</li>
<li>Navigation</li>
<li>Navigation</li>
</ul>
<div id="main"></div>
</div>
<div id="footer"></div>
</div>
Image courtesey of Sony's Uncharted series.
overflow:auto and why it's importantI just thought I would note here why there is an overflow:auto on innerContainer. overflow:auto is useful because it causes a div to expand to fit it's contents (for more on this, see The CSS overflow property and why it's so useful). When you have floated elements inside a container, it is vital that the container stretch to fit the elements inside. If it doesn't the float will leak out and affect the rest of your page.
You might still be wondering what happens if the navigation is longer than the main content. The way to get round this is to give the main content a min-height that is greater than the height of the navigation. In the example above, I have given my div called main a min-height of 400px which looks good even when the page is resized. Note: this will not work in IE6, as IE6 doesn't support min-height (although I'm sure there are no surprises there).