Creating Semantic 2-Column and 3-Column CSS Layouts

by Jake Rocheleau

on December 27, 2012

in Tutorials

Website layouts are not the most difficult part of coding a typical design. But unfortunately there are still not many standards set in stone for creating multiple column-based layouts. These are often put together through various CSS methods, but the most supported designs are using fluid width containers.

In this tutorial I want to look over a series of different CSS column layouts. We can see how to build websites using floats and direct positioning. Most common websites will utilize 2 or 3 columns at most, so that is what we’ll be focusing on. Along with these ideas you should feel comfortable trying out other CSS codes. There are new standards being written so frequently it can be difficult to gauge the best possible solution.

Absolute Position Fixed Columns

Using my first example I want to demonstrate a common website theme which uses 2 sidebars along with a center body area. The 2 side columns will be set to a fixed width while the center content should be fluid as you resize the window. This can be accomplished using a single container for all 3 columns, then positioning each sidebar to the right and left sides.

<div class="container">
  <div id="left">
    left col.
  </div>
  
  <div id="content"> <h1>here is some main text.</h1>
  <p>here is a brief paragraph with some elongated text. we can see if it will break the lines and where the columns begin to appear.</p>
  
  <p>Isn't this a neat little trick?</p>
  </div>
  
  <div id="right">
    right col.
  </div>
</div>

I am also placing additional padding into the center div container. When we setup absolute positioning on the columns this will automatically remove that content from the natural document flow. So all our center content is setup using width: 100% and would fall behind these sidebar columns.

/**
 * html-css column layouts
 */
html { background: #f06; background: linear-gradient(45deg, #f06, yellow);
min-height: 100%; }
div { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }

.container { display: block; position: relative; max-width: 1000px; min-width: 550px; margin: 0 auto; }

#left { width: 220px; background:#c9c; position: absolute; left: 0; top: 0; height: 100%; }
#content { width: 100%; background: #fff; padding: 0px 220px; }
#right { width: 220px; background: #a4a; position: absolute; right: 0; top: 0; height: 100%; }

Another nice part of using absolute positioning is that your sidebar columns will naturally fill the background space. Using other methods the sidebar BG colors will only be as long as the content. This is perfectly fine if all your background is the same color, but otherwise absolute positioning is a very solid method. I’ve setup a gist sample demo if you want to see this live in your browser.

absolute positioning CSS layots screenshot Gist

Floated Columns

While we are looking into the left/right layout style I want to bring up another solution. Floated elements are still kept inside the document flow, which is nice in certain instances. There is nothing wrong with absolute positioning except that it doesn’t always scale properly.

We can build the same type of layout using floats coupled with the same container element. However there are just a couple small issues which stand out in comparison. One major point is that you’ll need to code any sidebars above your main content area in the HTML DOM. No matter how you float these elements in the layout, you’ll need to have the sidebars appear first in the webpage content.

<div id="wrapper">
<div class="container">
  <div id="right">
    right col.
    <p>here is a line.</p>
    <p> and nother</p>
    <p> and nother!!</p>
    <p> gonna keep going.</p>
    <p>heyoo</p>
    <p>heyooooo</p>
  </div>
  
  <div id="left">
    left col.
  </div>
  
  <div id="content"> 
  
  <h1>here is some main text.</h1>
  <p>here is a brief paragraph with some elongated text. we can see if it will break the lines and where the columns begin to appear.</p>
  <h2>here is more big text and will this break the bank?? will it?? i dont really know to be honest.</h2>
  <p>but let's find out folks.</p>
  </div>
</div>
</div>

This is still perfectly semantic code because we’re only using HTML5 elements and attributes. It just gets weird presenting content into search engine crawlers, where your sidebar area locations appear slightly out of place. But the other pressing issue is that your sidebars will not adjust to 100% height if the body content is longer.

/**
 * html-css floated column layouts
 */
html { background: #f06; background: linear-gradient(45deg, #f06, yellow);
min-height: 100%; }
div { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }

#wrapper { max-width: 1000px; min-width:750px; margin: 0 auto; }
.container { height: 100%; float: left; background: #fff; }

#left { width: 220px; height: 100%; background:#c9c; float: left; }
#content {width: 100%; height: 100%; padding: 0 220px; background: #fff;  }
#right { width: 220px;  height: 100%; background: #a4a; float: right; }

.container { display: inline-block; }
.container:after {
    content: " ";
    display: block;
    height: 0;
    clear: both;
    overflow: hidden;
    visibility: hidden;
}
.container {
    display: block;
}

Unfortunately even appending a clearfix onto the container will not always fix this issue. The best solution is to create a single image 1px high and fill it repeating vertically down the page. This isn’t the most elegant solution, but it works if you need sidebars with differing backgrounds. Also you may consider this solution for similar layouts using 2 or 4 columns. Check out my related gist example with the same HTML/CSS code.

sidebars floating css clearfix background height bugs

Fluid Equal Height Columns

My next layout style is actually derived from Matthew James Taylor who wrote an excellent piece on this topic. He explains how we can build columns which float and also have full 100% height for background colors. It requires adding a new container div for each of the columns, and then hiding any overflow content.

<div id="wrapper">
  <div id="container3">
    <div id="container2">
        <div id="container1">
          <div id="col1">
            <h1>this is the right col</h1>
            <p>i am just saying that this is crazy folks. just super crazy!!!!!!!</p>
          </div>
          <div id="col2">Column 2</div>
          <div id="col3">Column 3</div>
        </div>
    </div>
  </div>
</div>

The code is very confusing if you don’t follow exactly what’s going on. We are basically pushing the first container way over to the right and then using relative positioning for the others. This means each of the containers is actually at 100% width but we display just a portion of each column. Then all the other content is hidden using the overflow property.

html { background: #f06;
background: linear-gradient(45deg, #f06, yellow);
min-height: 100%; padding-top: 55px; }

#wrapper { display: block; max-width: 1100px; min-width: 700px; margin: 0 auto; }

#container3 { float: left; width: 100%; background: green; overflow: hidden; position: relative; }
#container2 { float: left; width: 100%; background: yellow; position: relative; right: 30%; }
#container1 { float: left; width: 100%; background: red; position: relative; right: 40%; }
#col1 { float: left; width: 26%;  position: relative; left: 72%; overflow: hidden; }
#col2 { float: left; width: 36%; position: relative; left: 76%; overflow: hidden; }
#col3 { float: left; width: 26%; position: relative; left: 80%; overflow: hidden; }

Now the biggest problem I’ve had using this solution is getting any column to stay fixed. The issue arises because the column background and the column content are two separate divs. So if we setup a fixed width on the content, our background color will slowly fade as you resize the window. This requires us to stick using percentages or possibly ems for measurement units.

Unless we can figure out a fixed-width solution this method is best used in fluid website layouts. And as mentioned earlier, you are able to customize this style using as many columns as you’d like. Check out the live gist demo and attempt resizing the window to see what I’m talking about.

CSS floating container layout matthew james taylor method gist dabblet

Fluid-Fixed-Fixed Columns

This will be my last example but it’s definitely a cool one. Instead of placing the sidebars to the left & right sides I’ll show how we can float them both next to each other. Using this method it’s possible to setup any combination of fluid/fixed while still keeping your HTML content in the proper order.

<div id="wrapper">
  <div id="contentwrapper">
    <div id="contentcolumn">
      <div class="innertube">
        <b>Content Column: <em>Fluid</em></b>
      </div>
    </div>
  </div>

  <div id="leftcolumn">
    <div class="innertube">
      <b>Left Column: <em>220px</em></b>
    </div>
  </div>

  <div id="rightcolumn">
    <div class="innertube">
      <b>Right Column: <em>220px</em></b>
    </div>
  </div>

  <footer>
    <a href="http://www.google.com/">Googies</a>
  </footer>
</div>

I have also incorporated a small footer element to demonstrate how you may clear further page content. Using my example we have a left content column which is fluid as you resize the window. Then both the sidebars are set to a width of 220px which doesn’t adjust on resize. The content area uses negative margins to limit the full page width. This stops content from appearing underneath the sidebars.

/**
 * CSS Liquid Layout (Fluid-Fixed-Fixed)
 */
html {
background: #f06;
background: linear-gradient(45deg, #f06, yellow);
min-height: 100%; }

body { padding-top: 85px; } 
#wrapper { margin: 0 auto; max-width: 1100px; min-width: 650px; background: #fff; }

#contentwrapper{float: left; width: 100%; margin-left: -220px; }

#contentcolumn { margin: 0 190px 0 220px; }
#leftcolumn { float: left; width: 220px; margin-left: -220px; background: #C8FC98;}
#rightcolumn { float: left; width: 220px; background: #FDE95E;}

footer { clear: left; width: 100%; background: black;color: #FFF;text-align: center;padding: 4px 0;}
footer a { color: #FFFF80;}

.innertube {margin: 10px; margin-top: 0; }

This is one of my favorite general layouts when it comes to more complicated column designs. It does require a bit of knowledge using CSS margins/padding but nothing overly difficult. It should be noted you can easily rearrange the two sidebars to appear on the left side by changing your HTML order, and adjusting margins accordingly. Here is my live gist example of the typical 3-column fluid-fixed-fixed layout style.

three column layout website design css code techniques

Final Thoughts

I hope this brief tutorial can be of use to web developers who need quick solutions for layout designs. The initial codes used to setup your website will become the foundation for each project going forward. You want to make sure the foundation is not only stable, but supported in all major web browsers.

Be sure to check out some of my demo examples sewn throughout this article. I have provided live demo examples for each column style and you may duplicate these layouts at your own will. It is my goal to provide easy code snippets for putting together websites on a whim. If you have additional ideas or questions feel free to share with us in the post discussion area below.

Powered by Shutterstock

About Jake Rocheleau

Jake is a digital researcher and writer on many popular design magazines. He frequently writes on topics including web design, user experience, mobile apps, and project management. You can find him all throughout Google and tweeting @jakerocheleau. Connect with Jake on google+