Two Column CSS Layout: The Absolute Basics

January 9th, 2008 in Design Tips & Tutorials

by: Matthew Griffin

This tutorial is for the designer who wants to get acquainted with the basics of CSS layout. There are a lot of articles floating around with advanced CSS tips and tricks but there seems to be a gaping hole where the basic tutorials should be. An article like this would have been tremendously helpful to me when I first started into CSS layouts. If you're about to to take the plunge I'm sure this will be helpful for you.    

DEMO HERE

I'm writing this tutorial with the assumption that you know basic HTML. If you don't know what <body> means, you need to get a good book on HTML before this will be any help to you. I am also assuming that you know how to create a .css file and link it to a web page. If you think you're ready, let's get started.

The <div> Tag: Basic Building Block of the CSS Layout

Whether or not you've messed with CSS layouts, you've probably seen the <div> tag. The <div> tag is a generic tag whose primary use is to DIVide blocks of content. In most popular HTML editors a set of <div> tags is created automatically when you select a block of text and change it's alignment. The resulting code would probably look something like this:

<div align="center">
    Here is my block of text
</div>

With a little help from CSS, the <div> tag can do more than just change the font and alignment of text. In fact, the <div> is the basic building block of the CSS layout. In a CSS layout, the <div> tag is a lot like the table cell used to be. But the <div> tag is more flexible and semantically appropriate for dividing content. The table cell should only be used to contain tabular data. In this tutorial, we'll use <div> tags to create a box or container around content and then we can use CSS to position the box, make the box wider or skinnier, taller or shorter, have a border, have a background, and a lot more. Here is some HTML and corresponding CSS to create a block of content that is 300 pixels wide, 200 pixels tall with a 1 pixel wide black border around it and 10 pixels of padding.

<div class="my_cool_box">
    Here is my block of text
</div>

<!-- Here's the CSS code -->

div.my_cool_box{
    padding: 10px;
    width: 300px;
    height: 200px;
    border: 1px solid gray;

}

The CSS determines how the box will look and, as you will see next, where it will appear on the screen. You will notice already, there is a clear separation of style information from content information. This is a very important concept to grasp if you are going to build websites correctly. Separating style from content will make your websites download faster, index more effectively on search engines, easier to redesign, and more accessible. Check out this article for more information on building a semantically correct content layer: Intro to Web Design: Building a Content Layer with HTML.

The Float Attribute: Tell Your Content What Side it Should Be On

 With the code above all you can do is create a bunch of boxes that iterate down the page. But most website have multiple columns to display content. That's where float comes in. Float tells a <div> box to appear to the right or left of the content around it. For example, in order to create two boxes that appear side by side like columns, we would do something like this:

<div class="my_left_box">
    Here is the left box
</div>

<div class="my_right_box">
    Here is the right box
</div>

<!-- Here's the CSS code -->

div.my_left_box{
    float: left;
    padding: 10px;
    width: 290px;
    border: 1px solid gray;
}

div.my_right_box{
    float: right;
    padding: 10px;
    width: 290px;
    border: 1px solid gray;
}

This code will produce two 300 pixel wide columns—one appearing in the upper left-hand corner of the screen and one appearing on the far right. Now we're getting somewhere.

Reining Your Layout in with a Wrapper

Okay, the next step is to rein the layout in—give it some boundaries. The example above will give you two columns appearing further and further apart depending on how wide the viewer's screen is. But we want our columns to appear right next to each other no matter how wide the screen is. To do this, we need to wrap our other two boxes with another <div> tag like this:

<div class="my_wrapper">

    <div class="my_left_box">
        Here is the left box
    </div>

    <div class="my_right_box">
        Here is the right box
    </div>

</div>

 

<!-- Here's the CSS code -->

div.my_wrapper{
    width: 630px;
}

div.my_left_box{
    float: left;
    padding: 10px;
    width: 290px;
    border: 1px solid gray;
}

div.my_right_box{
    float: right;
    padding: 10px;
    width: 290px;
    border: 1px solid gray;
}

The <div> tag in the class "my_wrapper" puts a box or container around our original content boxes and makes sure that they don't wander to the edge of the screen. The example above will produce the same two boxes but this time they will be right next to each other because the wrapper <div> keeps the right box from floating any further than 600 pixels. Usually  you will put some kind of wrapper <div> around all the HTML inside your <body> tag.

PITFALL: Always make sure to specify the width of the columns inside your wrapper. If you use Firefox, the layout will look fine but IE will place your columns on top of each other.

Don't Forget to Clear

Some of the most frustrating moments I had when I was learning CSS layouts revolved around the "clear" attribute. Clear makes your content stop wrapping around <div>s that are floating to the right or to the left. For example, if you have a two column layout and below the two columns is a footer that spans the length of both columns, you don't want that footer content to wrap around what is above it. In order to make sure it doesn't, you will have to specify that the footer <div> clears both columns and starts fresh. The code below will produce the same two columns we had before and a footer box below them.

<div class="my_wrapper">

    <div class="my_left_box">
        Here is the left box
    </div>

    <div class="my_right_box">
        Here is the right box
    </div>

    <div class="my_footer">
       Here is the footer
    </div>

</div>

<!-- Here's the CSS code -->

div.my_wrapper{
    width: 630px;
}

div.my_left_box{
    float: left;
    padding: 10px;
    width: 290px;
    border: 1px solid gray;
}

div.my_right_box{
    float: right;
    padding: 10px;
    width: 290px;
    border: 1px solid gray;
}

div.my_footer{
    clear:both;
    padding: 10px;
    width: 610px;
    border: 1px solid gray;
}

Building a Header and Dealing with Overflow

By now the system should be starting to make sense but we need to take a moment to tackle an important issue and a potential pitfall. When you place images inside <div> boxes, and you need the box to be a specific height, always remember to set the overflow of the <div> to hidden. For example, when your are building the header for your design, you might have a logo that is 100 pixels high and you want to make sure the <div> box is exactly 100 pixels high as well. You will set the height of the box to 100px and then specify "overflow: hidden". This fixes a very annoying little bug in IE that will cause some unwanted padding to appear at the bottom of your <div>s. Now, let's add our header. The header HTML will go inside the wrapper just above "my_left_box" and will look like this:

<div class="my_header">
       Here is the Header
</div>

 

and the CSS for the header will look like this:

div.my_header{
    padding: 10px;
    width: 610px;
    height: 100px;
    overflow: hidden;
    border: 1px solid gray;
}

Simple Horizontal Navigation with <li>

We're almost finished. The last important piece of the CSS layout is the <li> tag. The <li> tag can be used to build a list of items either horizontally or vertically. In this case, we are more interested in the horizontal list. Using the <li> tag and a little CSS we are going to build a horizontal nav bar at the top of our layout. Here is the final example in all it's glory:

<div class="my_wrapper">

   <div class="my_header">
       Here is the Header
       <ul>
          <li class="my_nav_link">Contact Us</li>
          <li class="my_nav_link">About Us</li>
          <li class="my_nav_link">Home</li>
        </ul>

    </div>

 

    <div class="my_left_box">
        Here is the left box
    </div>

    <div class="my_right_box">
        Here is the right box
    </div>

    <div class="my_footer">
       Here is the footer
    </div>

</div>

<!-- Here's the CSS code -->

div.my_wrapper{
    width: 630px;
}

div.my_header{
    padding: 10px;
    width: 610px;
    height: 100px;
    overflow: hidden;
    border: 1px solid gray;
}

    li.my_nav_link{
       text-align: right;
       float: right;
       list-style: none;
       padding-left: 15px;
    }

div.my_left_box{
    float: left;
    padding: 10px;
    width: 290px;
    border: 1px solid gray;
}

div.my_right_box{
    float: right;
    padding: 10px;
    width: 290px;
    border: 1px solid gray;
}

div.my_footer{
    clear:both;
    padding: 10px;
    width: 610px;
    border: 1px solid gray;
}

This final example will produce a layout with a header, two columns, a footer, and a horizontal nav bar. The final addition we made to the code—the <li> tag trick—can be helpful in a lot of situations. Just remember to set "clear: both" on any <div> tag appearing after one of these <li>s. The "overflow: hidden" pitfall can also apply to <li>s so watch out for that.

DEMO HERE

Another solution to this problem is to set the "position" attribute of the nav <ul> tag to absolute and then specify a "top" and "left" attribute to position the nav bar exactly where you want it on the grid. If you use this method, though, make sure to set the "position" attribute of the containing tag (in this case it's the <div> in the "my_wrapper" class) to "relative". If you don't, the absolute positioning of the nav bar will be relative to the upper-left corner of the screen rather than the upper-left corner of your design. This is especially important if you are coding a layout that is center-aligned.

You should know enough to be dangerous now. Next comes the tinkering and the hair pulling. Check out these articles if you want to go a little deeper.

Pushing the Limits (Part 1): The Perfectly Semantic Three-Column CSS Layout

Pushing the Limits (Part 2): A Simple Four-Column CSS Layout with a Little Divitis

Pushing the Limits (Part 3): Building a Semantic Four-Column CSS Layout

Indestructible Website: How to Build an EM Based Layout that Won't Break

UPDATED 11/5/2009

  • 53 Comments
  • 216716 Views

Comments

Posted By: Teppo on 01/10/08

Just wanted to point out that you're having a case of classitis here. Why "li.my_nav_link" when you could just use "ul.my_nav li"? Or better yet, use "div.my_header ul li" unless you're planning to use non-navigation lists in header. Cheers. :)

Posted By: Andris on 01/10/08

thanx for this good tutorial. 2 things: the width of the header and the footer should be 608px. you forgot the 1 px border. and you forgot the ; after the clear:both; in the div.my_footer.

Posted By: Jon on 01/10/08

thanks

Posted By: frank on 01/10/08

I'm sorry but I think someone needs to go back to school themselves! This is a load of rubbish. Have you even looked at the final result of your code in a web standards compliant browser?

Posted By: Sean on 01/10/08

Man you guys are harsh... the title of the article is "The Absolute Basics." That's what it is - I see this as the perfect article for someone looking to learn CSS beyond font colors and sizes. You don't want to give a CSS newb too much info. Start with these basics, then talk about how to minimize class usage, then talk about standards compliance. That's my 2 cents worth anyway. Good article!

Posted By: frank on 01/10/08

Sean, thats what I'm concerned about, if a newbie came along and used this code it simply would not work. This article should be titled "Intermediate coders spot the mistakes!"

Posted By: Matthew Griffin on 01/10/08

Thanks for all your comments (especially you, Sean). I knew when I posted this tutorial that I would most likely get bad reviews from some purists. What I wanted to accomplish here, though, was to give the novice a general understanding of how CSS takes the jump from font size and color over to layout. In my opinion, the multi-level hierarchies would be too much. As for the final results of the code, Frank, I tested them in all the major browsers--not sure what your issue is. Andris, sorry about the typo. I will fix that.

Posted By: Teppo on 01/10/08

Even though it's reasonable to keep things simple for beginners, I must disagree with Sean: in my opinion standards compliance and good practices should be considered right at the beginning. It's much easier to learn doing things properly than unlearning bad practices later. Just trust me on that one. By the way, I'm sorry if I was being harsh - it's just that this "making newbie tutorials simple by sacrificing good practices" has been bothering me for quite some time. It's still nice to see people sharing their knowledge. :)

Posted By: on 01/10/08

Point well made, Teppo. I did run the code through W3C for validation before I posted it so I know that it IS standards compliant. I just left out some of the more advanced techniques for this particular tutorial. For Teppo's sake, if anyone wants to dig deeper into advanced CSS techniques, check out alistapart.com or get a book by Eric Meyer.

Posted By: Walter Earnshaw on 01/16/08

Hi_there Thanks for a useful AND informative tutorial on the CSS basics. Most of these kind of tutorials are not basic enough. Ignore the whingers - I suppose they are only trying to show what they know, not understanding what the basic bods need Yours elwaltura ps Hope there will be more to come.

Posted By: on 01/16/08

Thanks, Walter. I will be doing sporadic tutorials in the future. I hope they are helpful.

Posted By: mark brand on 02/17/08

matthew you did good. walter got it right. don't let the negative comments put of you doing another. cheers mark

Posted By: on 02/18/08

Thanks, Mark. It's much appreciated.

Posted By: Juan Garcia-Garcia on 02/22/08

Very good introduction to creating layouts, clear and to the point. Thank you!

Posted By: Chris Monahan on 04/09/08

Surely "display: inline;" would create horizontal navigation lists easier?

Posted By: Belinda Matson on 04/23/08

Fantastic, I have learnt html from tutorials online and am now trying css and you give what newbies need, I have looked at around 20-30 tutorials on css and been lost as the tutor assumes readers have some basic even intermediate css knowledge. This is basic and it explains which code does what and why you need it, what more could any newbie want? I'm very grateful, thank you.

Posted By: on 04/23/08

You're welcome, Belinda. Glad I could help.

Posted By: R.L.Harris on 05/04/08

VERY VERY HELPFUL. THANKS ALOT BODDY. ---RON FROM BUZZWAVEAVENUE.COM----

Posted By: amy on 05/09/08

thankyou it was very helpful. none of the other tutorials really make sense or give proper examples so thankyou :)

Posted By: Web Gyver on 05/26/08

Kudos Matthew! You're doing a great job explaining the basics . . . and showing how to make it actually work. No matter how often I work with CSS layouts, going back to the basics is an absolute must after a two-month break -- you know, do some database work, design some graphics, create some Flash and then do some web page layouts again -- and I'm bookmarking this page for good! Thanks!

Posted By: Internetagentur on 01/19/09

Thank you ... this tutorial has me very helped.

Posted By: yerel secimler on 02/03/09

Thank you

Posted By: Jim on 04/24/09

Why not just provide an example?

Posted By: San Diego seo services on 06/04/09

Thumbs up to you Matthew..! Whatever the others said, for me and to other satisfied readers, you really did a good job! more power! -richard

Posted By: Jackson Lim on 06/05/09

To me this tutorial is an excellent stepping stone to those, like me who just want the absolute fundamental. A lot of advance people might disagree with your method, but to us the Noobs, you did an excellent job. Bravo to you.

Posted By: Matthew Griffin on 06/05/09

Thanks, Jackson. I actually hope to update and expand this article in the near future so hopefully it will continue to grow in its helpfulness to those new to multi-column CSS layouts.

Posted By: lida fx15 biber hapi ikibindokuz seo yarismasi on 09/25/09

Very good introduction to creating layouts, clear and to the point. Thank you!

Posted By: Charbz on 09/30/09

Thanks a lot. I was looking everywhere on how to create two columns and this is the best way by far! :)

Posted By: Robert on 10/21/09

Thank you for the tutorial. I'm already at the hair-pulling stage myself. I'm not trying to be a purist, as I'm really pretty noobish, but I thought it was "bad" to specify column widths in pixels. Somewhere I read that you were supposed to specify column widths only in percentages (of their parent container) so that the page wouldn't require horizontal scrolling in narrow browsers. Anyway, whether what I read is true or not, why is CSS such a mess? Formatting text on a computer has been around since at least the 70s, but CSS seems to have been put together by a committe without a clue about formatting.

Posted By: Eric Constantine on 11/03/09

A fine tutorial:) Good english my man! Every british captains praises your fine form! You would be an asset to her royal navy:) Beyond all this whether we are good or not at anything, such as explaining things via tutorials is dependent on the quality of the thought structure of the teacher. This is one of the best I have seen:) Cheers! And this is, to be certain, a fine website my fine sir:)

Posted By: Matthew Griffin on 11/03/09

Why, thank you my good man.

Posted By: Matthew Griffin on 12/02/09

Mohan, check out the other articles I linked to at the end of this one.

Posted By: Commandrea on 01/13/10

I found this very helpful! It put a lot of things into perspective. Thank you, thank you!

Posted By: Matthew Griffin on 02/02/10

Thanks, I'll keep that in mind for a future article.

Post Your Comment

Comments are closed.