First time visitor? The tutorials start here.

Flexible-width, content-first layout with fixed-width, equal-height sidebar

Wow, that’s a wordy title, but I wanted to make sure people will know what to expect before they click on my link.

To see what you’ll be creating today, see a working example here.

Creating this type of layout without tables may sound like a tall order right now, but not only will I show you how to do it, I’ll also try to help you understand how it works so you’ll be able to create these things without the need for a cheat sheet later.

Nope, it won’t take a miracle. Just a little 2+2. Ok, maybe 20+80, or 25+75. Ready? Here goes…

Putting everything in order

As I’ve mentioned many times before on this site, search engines read your pages from the top of the markup (HTML or XHTML) and work their way down, and won’t always index your whole page. If you have a lot of links before the real content, this can be very bad for your search engine rankings.

Likewise, aural screen readers (speech synthesizers that read web pages out loud) will also read from the top down, and you don’t want to annoy your blind visitors by making them hear the same long list of links before getting to the real content, every time they load a new page of your site… Do you?

Here is how the content should appear in your markup (XHTML):

  1. Header
  2. Content
  3. Sidebar
  4. Footer

Makes sense, right? I mean, isn’t that the order you would want to read everything in? You go to a page, and the header will generally have the name of the website in it. Often, it will also have navigation for the main sections of a website. Then, you would probably want to go straight to the content.

After reading an article, you might then want to look for sub-sections of that website for similar content, or see what other sites the webmaster recommends, and the sidebar is a good place to put all that stuff. Whatever you would put at the bottom of the page, of course that will go last in your XHTML.

Now, let’s translate that order into XHTML. Create one <div> for each of the 4 sections (header, content, sidebar, footer), and give each of those 4 sections its own unique ID so you can style each section later with CSS. The purpose of each section should make it easy to come up with names for those IDs…

<div id="header">
         Header content here
</div><!-- end header -->

<div id="content">
         Main content here
</div><!-- end content -->

<div id="sidebar">
         Sidebar content here
</div><!-- end sidebar -->

<div id="footer">
         Footer content here
</div><!-- end footer -->

Flex-width sidebar with flex-width content

If you want the width of both your sidebar and your content to be flexible, this is simple. Just define the width of each in % sizes, then float your content to one side and the sidebar to the other, like so:

#content { width: 75%; float: right; }
#sidebar { width: 25%; float: left; }

That said, this can be dangerous. If someone is looking at your page with a small screen resolution and there is something in the sidebar that makes it wider than 25% of the screen, the sidebar will be pushed down below the content. For this reason, you might want to try a fixed width on the sidebar and a flexible width on the content.

This is where the trick comes in.

Fixed-width sidebar with flex-width content

For this trick, you’ll need to add a div around your #content div. Since this will be used to offset the margin, I like to name this div “offset”.

<div id="offset">
      <div id="content">
              Main content here
      </div><!-- end content -->
</div><!-- end offset -->

Now in your CSS, you’ll want to give that #offset a width of 100%, float it away from the sidebar, and give it a negative margin on the side of the sidebar, that is big enough to accommodate the sidebar. Let’s say, for instance, you want the sidebar on the left:

#offset {
	width: 100%;
	float: right;
	margin-left: -215px;

We floated it to the right because the sidebar will be on the left. We also gave it a margin-left of -215px (negative 215px). This is counter-intuitive, because a negative left margin should pull an element to the left. However, this is what we need to do.

If we wanted the sidebar on the right, we would float #offset to the left and use a negative margin-right instead of margin-left.

The next thing in our CSS is #content. Sticking with a left sidebar:

#content {
	margin-left: 215px;

We added a positive left margin, which is exactly the same width as #offset’s negative left margin.

Again, if the sidebar is on the right, we would change margin-left to margin-right.

Finally, the sidebar itself:

#sidebar {
	width: 215px;

That part is pretty self-explanatory. We left enough room for a 215px-wide sidebar, and we have a 215-px wide sidebar. If you prefer to add padding to that, you would decrease the width of the sidebar, because that padding will add to its width.

For example, you could define a 205px width, and add 5px of padding on the left and 5px on the right. So, instead of the above, you would have this:

#sidebar {
	width: 205px;
	padding: 0 5px;

The padding definition above is written in shorthand, which you can find explained here: CSS margin and padding attributes.

Changing the width of your layout

If you don’t want your layout to take up the full width of the page, you will need to add a div around the whole thing. Since it will “contain” everything, let’s name it “container”.

Add only the two lines in bold below:

       Head code goes here

<div id="container">
    <div id="header">

        The rest of your page code here
    </div><!-- end footer -->
</div><!-- end container -->

Now to change the width of your layout, you only need to define the width of your container. For example:

#container { 
	width: 90%; 
	margin: 0 auto;

Again, the margin is shorthand. The zero defines the top and bottom, and the “auto” defines the left and right. When “auto” is used for both left and right margins, this puts the element in the horizontal center of the page.

Equal-height sidebar and content

For this, we’ll use the same technique as described in my tutorial, “Equal-height columns with CSS,” as the sidebar is really just another column.

Since you want to make the sidebar and content equal heights, you’ll need to surround those two divs with a “column wrapper,” as I call it. This will differ slightly from my original tutorial, however, because you’ll also need to surround the “offset” div that offsets the content div.

<div id="column_wrapper">

      <div id="offset">
            <div id="content">
                  Content stuff
            </div><!-- end content -->
      </div><!-- end offset -->

      <div id="sidebar">
            Sidebar stuff
      </div><!-- end sidebar -->
</div><!-- end column_wrapper -->

Then, add the following CSS:

#column_wrapper {
	overflow: hidden;
	float: left;
	width: 100%;
	position: relative;
	z-index: 10;
#content, #sidebar {
	padding-bottom: 50em;
	margin-bottom: -50em;

For an in-depth explanation of how this works (remember, the sidebar is just another column), see my tutorial from last month, Equal-height columns with CSS.

If you add a footer below the content and sidebar, you will need to give your footer relative positioning, as well as a z-index that is larger than “10”. This is to account for a bug in some versions of Internet Explorer that will have the columns covering up the footer if you don’t do this, which is explained in my aforementioned equal-height columns tutorial.

For a complete solution and working example of all these techniques in action, see Fluid-width, content-first, equal-height sidebar layout example. I powered that page with PHP, making it possible for you to see an example and solution for both a left sidebar and a right sidebar. Under “CSS for this layout,” I highlighted in red, the only three parts that change between a left sidebar and a right sidebar.

Enjoy your new-found power. 🙂

If you found this article useful, please spread the word:
Stumble it! Digg! Tweet it!

Questions or comments?

Please log in to post a comment. Sorry, but it prevents this from happening. If you're not registered yet, you can register here.