Though a lot of web developers are beginning to migrate to css in their sites I still see many developers struggling when using css to layout their sites. CSS styling is usually pretty easy to grasp, but it can take some time to get comfortable with using css positioning techniques to layout a site. All too often I see the same developers moving back to tables so I thought I would present a few simple layouts, beginning here with a 2 column css layout.
I’ve created a 2 column layout using css, keeping things as simple as I could. Instead of just presenting the layout I want to work through the code here and explain some of the common pitfalls that I’ve come across and show how this simple layout overcomes those obstacles.
There are plenty examples of css layouts online though most of the 2 and 3 column ones that I’ve seen only include the columns themselves. I’ve included both a header and a footer in my layout. While the header is easy to include the footer tends to trip people up so I wanted to add it here and offer some explanation about how to integrate it into the layout.
The image below is a typical layout for many websites. A header at the top, a menu to the left, a main content area to the right, and a footer at the bottom. You might see something like this centered on the page. You can click the image to open it in a new window or tab and view the source code while reading about it here.
Let’s look at the basic html structure for the page and then see how css is used to layout the various elements. The html structure is quite simple.
<div id="page"> <div id="header">Header</div> <div id="menu">Menu</div> <div id="content">Content</div> <div id="footer">Footer</div> </div>
We have each of the four sections of the page represented by a single div and then all four are enclosed in a ‘page’ div. The ‘page’ div is included so we can center everything in the browser window. There’s not much exciting going on here and it’s rather basic. All you need to notice is that each element is represented by a single div and that the order they sit in the structure is pretty straightforward as well. Nothing in the structure itself indicates that the layout will be in 2 columns.
Of course the interesting part is the css which surprisingly is rather simple as well. In fact only one of the elements even needs css positioning applied to achieve the layout. Can you guess which one? Let’s look at the css for each of the elements one at a time in the order they appear in the html structure.
Page Div
The page div is included in the layout to center everything. It’s represented by the thin purple border around everything on the page. It’s not really necessary in the 2 column layout, but I’ve included it since many sites are centered in the browser and some people have trouble doing this with css.
div#page {
border:1px solid purple;
width:755px;
margin:0 auto;
padding:5px;
text-align:left;
}
div {
text-align:center;
}
The border, padding, and text-align are purely for formatting. The text-align on the generic div is to center the single word of text within each div (header, menu, content, footer). I needed to add the text-align:left to the page div or it tries to center the 4 divs inside it in Internet Explorer. While you might use any or all of these properties they have nothing to do with the centering of the overall page.
To center the page you need a width which I’ve specified here in px, but could be any valid width such as % or em. You also need a margin which is set to auto for the left and right margin. If you’re not familiar with css shortcuts the way I’ve specified margin here is the same as saying 0 for the top and bottom margins and auto for the left and right margins. That’s all it takes to center your page. Just wrap your entire page in a div, give it a width and set the left and right margin to auto. You also need to use a proper doctype for your html in order for this to work in Internet Explorer.
Header Div
The header div is even more unremarkable than the page div. All I’ve included is a border so you can see it and a height and width. In real pages I’d typically set the width to be 100%, but used px here for no real good reason.
div#header {
border:2px solid red;
width:750px;
height:30px;
}
The header appears just where you might expect. Since it’s the first element inside our page div it displays right at the top of the page. As it does that automatically there’s no reason why we need to add any kind of css positioning to it. In fact not adding any positioning to it will make it easier to set the menu and content divs.
Menu Div
Again the menu div has a border and I’ve also applied a width and height to it. Nothing really new here. There’s also a margin which I’ve used just to give the div a little space from the border of the page div. The menu div is our one positioned element. Did you guess it was the menu div? Let’s look at the code to see how it’s positioned.
div#menu {
border:2px solid green;
width:200px;
float:left;
margin:10px 0 10px 5px;
height:350px;
}
The menu div is positioned by floating it to the left. When something is floated in css it’s taken out of the normal document flow. As far as the other elements on the page are concerned it’s been removed from the same document space they occupy and other elements can thus occupy the same document space. I think this is one of the harder aspects of css positioning to grasp. In this layout unless we tell it otherwise the next element on the page (in our case the content div) will want to sit in the same exact place the menu div sits. It can since as far as the content div is concerned the menu div has been removed from the document so to speak. With floated elements it’s not quite that simple, but for the purposes of this layout we can stay with this simple concept of document flow.
Content Div
As with the other divs the content div has a border applied to it as well as a width. Again nothing special about either of these. I do want to discuss each of the three other css properties so let’s take a look at the code
div#content {
border:2px solid blue;
width:500px;
margin:10px 0 10px 235px;
min-height:500px;
_height:500px
}
The get the content div to display where we want we don’t need to use css positioning. Here all that’s been done is to give it a left margin to place it to the right of the menu. Remember that without doing anything the content div will be located all the way to the left in the same space the menu div occupies. Again that’s because the menu div is no longer in the normal document flow due to the float. You can test this by copying the source code and removing the 235px from the left margin and see where the contnet div moves.
CSS positioning could have been used either by floating the content div or using absolute or relative positioning. I think this is the common first thought when creating a css layout. The instinct is to use positioning on everything. But there’s a reason why I didn’t use it. I want to keep the content div in the normal document flow. Keeping it in the normal document flow helps to keep the footer div always sitting right below it. Had positioning been used and the content div been removed from the document flow as well as the menu then the footer would want to occupy the space just below the header.
The menu div usually has a fixed amount of information in it and generally won’t change height from page to page. The content div however will often change height based on the how much content it contains. Most of the time there will be enough content so that it has a height greater than the menu. When it does the footer will sit at the bottom of the page and everything will look great. But if the content isn’t enough to give the div a greater height than the menu the footer will come up to sit below the content (now shorter than the menu) and will end up overlapping the bottom of the menu.
Because of this I’ve added a min-height to the content div. The min-height assures us that the content will always have a greater height than the menu div. If the content needs the div to grow longer it will automatically, but by adding min-height we can be sure it will never be too short. Unfortunately Internet Explorer doesn’t handle the min-height property and so I’ve used _height as a sort of min height hack. IE actually interprets _height as height and all other browsers ignore it. Fortunately Internet Explorer will still expand past this height when the content needs it to so _height does act the same way as min-height. Incidentally you can use an underscore in front of any css property and know that only IE will interpret it. I’ll use this sometimes when I need IE to have a different value for a property than other browsers. Just make sure to use the underscore version of the property after the valid property.
Footer Div
Because we’ve accounted for the footer div in the way we set up the content div nothing special needs to be done to it. It looks exactly like our header div in fact. Just the by now familiar border, width, and height.
div#footer {
border:2px solid red;
width:750px;
height:30px;
}
i think footers cause a lot of problems for people when they begin to layout a page with css instead of tables. I see lots of questions about how to position it and others asking why it’s not sitting where expected. Here by not using css positioning on the content we’ve solved the problem and let the footer naturally sit at the bottom of the page where we want.
This simple structure has been built as a 2 column css layout. No tables allowed (unless you have data for your content that should make use of a table). Even though our 2 column layout uses css to position the various elements we only needed to use css positioning on one element in our layout. Keep that in mind as you develop your own layouts. Just because you’re not using tables doesn’t mean you need to use css positioning on everything. By limiting the use of it here we’ve simplified things and eliminated some problems that often arise.
By no means is this the only possible way to develop a 2 column css layout. Below are some links to other css layout resources that may also help in the development of your sites. Feel free though to use my 2 column css layout as a basic structure in your own sites.
Resources
Layout Reservoir
CSS layout techniques
Layout Boxes
Popularity: 48%
Subscribe to
TheVanBlog |
Email This Post













Thank you. After looking at so many explanations….this one made sense!!
Very appreciative.
Ella
Glad I could help ella. When I looked around at other css templates I didn’t see much in the way of explanation so I tried to make this one simple and understandable. Keep in mind that this isn’t the only way to code a 2 column css layout. It’s just one way and the way I chose when writing this post.
Glad it was helpful.
THANK YOU VERY MUCH..
CSS never sounded soo understandable in any tutorial to me. Thanks alot for this post. You saved me from quite a trouble. Keep writing pal.
regards…
Glad I could help Pasan.
Excellent example - thanks! Very simple and easy to understand.
Glad I could help.
Hello,
I am a newbie to CSS. I like the simplicity of your 2 column CSS based layout and I haven’t found any other website that explains so clearly. However, I am having trouble rendering even the basic 2 column in IE7. The “Menu” column always floats away. But it is NOT a problem in FF3. Any suggestions? Thanks. You can view the file at:
http://garnet.acns.fsu.edu/~tsomasun/van.html
The code is copied directly from your tutorial.
Thanks for the compliment Thay.
The one thing I notice is in your css file you’ve repeated the html structure at the top
Try removing this code from your css file:
<div id=”page”>
<div id=”header”>Header</div>
<div id=”menu”>Menu</div>
<div id=”content”>Content</div>
<div id=”footer”>Footer</div>
</div>
When I look at the page I created here in IE7 it is working. The html above in the css file is the one major difference I’m noticing and I think it may be causing the problems you’re seeing. I think it’s canceling the css for div#page below it somehow. Without that wrapper div the menu floats to the left edge of the body.
Somehow in your example the menu div isn’t seeing the page div as it’s container. It sees the body as its container and floats to the left edge of the body.
I hope that makes sense.
I do think the issue is in the html code in the css file. I think if you remove it everything will work.
If it doesn’t let me know and I’ll be happy to take another look.
Steven,
Thanks a lot. I didn’t realize that I left the code hanging in there (.css). I was trying to debug the .html code rather than look at the .css file, showing that I have lot to learn and think slightly differently.
Thanks. Keep up the good work.
Glad to help Thay. Sometimes you need that second set of eyes. It’s easy to get caught trying to debug something when the problem is really someplace you aren’t looking.
I can’t even begin to count how many times I’ve done the same thing.
Thanks for this tutorial. I’ve been looking for a 2 column layout with header and footer and yours is the first one I’ve found that falls together nicely and with a minimum of code. Your explanation makes a lot more sense than others I’ve tried also.
I was going to ask you how to get the menu to expand to 100% height but I just figured it out by copying the height data for the content to the menu and it worked.
Thanks much!!
Glad to help Lori. I tried to keep this post to a minimum amount of code to make the basic concepts easy to understand.
I actually layout a site a little differently than I talk about here. I now float both columns to the left and then use clear: both on the footer to hold it below the columns. But the method here still works.
One of these days I’ll update this post or write a new one on how I code things now.