Mobile version (Display Regular Site)

Skip to: Navigation | Content | Sidebar | Footer

Weblog Entry

Friday Challenge

January 23, 2004

Whether it’s a deceptively simple problem or a case of being too close to the code to see the easy answer, I’ve been struggling with this one problem on and off for months now:

Is it possible to use floats to position a fixed-width sidebar on the right of a page, with a liquid content area, if the content comes before the sidebar in the markup?

Floating, and not absolute positioning is necessary for the sake of a clearing footer. It’s easier to see what I’m after by looking at the code:

<div id="content">

<div id="sidebar">

<div id="footer">

Corresponding CSS:

#content {
 float: left;
 margin-right: 210px;
#sidebar {
 width: 200px;
 float: right;
#footer {
 clear: both;

Simple, right? Should work? Well, check the test page. If the order of the content and sidebar divs is reversed (and the float is switched accordingly), then it works like a charm.

But why should the sidebar need to go before the content in the code order? “Skip nav” links can route around this if absolutely necessary, but CSS is about freeing presentation from content after all.

Note that floats are reliant on code order, and do work best with defined widths, but with the proper CSS you should be able to get a simple two-column layout working. Shouldn’t you?

I can’t. And I’m hoping there’s a ridiculously simple solution to this, and I’ll look silly for even posting it. But since I keep running into the wall, here’s what I’m going to do.

First person to reply with a solution that gets it using just floats, without changing the order in the test markup (that is, content first, sidebar second, footer last) gets a copy of the upcoming second edition of CSS: Separating Content from Presentation which I contributed to, whenever it’s published.

Again — 1) no changing the order of the code (although adding new divs would be fine), and 2) no using absolute positioning unless you can somehow make it work with the footer. Other than that, the sky’s the limit.

Update: Well that was quick. Ryan Brill takes the prize, with his creative negative margin solution. It tests fine in Safari, Firebird, Konqueror, all versions of IE 5+ (Win & Mac), Opera 6+, and even kinda-sorta works in NN4. Great job Ryan!

Reader Comments

Josh Sowin says:
January 23, 03h

Wow, I thought it would be easy but 10 minutes of playing and it didn’t want to work.

That’s really weird, but explains alot of trouble that I’ve had in some of the recent sites I’ve done…

January 23, 03h



would it be possible to set the left hand box to a percentage width…kind of like ALA did before the redesign?

Josh Sowin says:
January 23, 03h

I tried that, but good luck making it work with much resizing. Setting it to 80% works on a large resolution but after you bring the window size down it knocks the sidebar to the bottom.

I was thinking maybe the content could go in a container that had an auto width, then set the content to 100% width, and it would resize automatically, but I couldn’t get that to work. I’m not very good with understanding inheritance at this point.

January 23, 03h

If both columns could be set to percentages, it might could work, but with the sidebar set to a static width…..that could be trouble.

Evan says:
January 23, 03h

<table width=”100%” border=”0” cellpadding=”0” cellspacing=”0”>
<tr><td>Content</td><td width=”200”>Sidebar</td></tr>
<tr><td colspan=”2”>Footer</td></tr>

Only took me two minutes! Pretty sweet, eh?

January 23, 03h

A concept I’ve been thinking about for a while seems to cut it. I set a width of 100% on a container div (wrapped around the content div), but then set a negative right margin of 210px (the width of the sidebar div plus 10px for spacing). Then, directly inside this container div, I set up the content div. This div has a right margin of 210px (same as the negative margin above), to force the content away from the left side of the screen. It works in IE 5, 5.5, and 6, Mozilla 1.5 and Firebird 0.7, Opera 7, and Netscape 6 and 7. I’m off on vacation for about a week, but if I can find an internet cafe, I’ll check in and see what type of bugs people have found, etc. I just whipped it up in 10 mins, and it’s only the second time I’ve ever tried using this concept (the first was a much simpler scenerio, and just a test).

Anyway, the URL for the test page is If I can’t find an internet cafe, I won’t be back until next Friday. Hope this helps. :)

Evan says:
January 23, 03h

Kidding, kidding…

DarkBlue says:
January 23, 04h

That’s a sweet solution Ryan.

Dave S. says:
January 23, 04h

Well, Ryan, that may just be it… I’ll run it through a few browsers this weekend, but I dare say the book is yours!

Josh Sowin says:
January 23, 04h


You, my friend, have just been added to my bookmarks (no RSS feed?). Great quick solution!

January 23, 04h

I don’t quite understand how Ryan Brill’s solution works, but it seems to do the job… I’m thinking the negative right margin would push the content off the right side of the page, or perhaps I don’t understand how negative margins work… :-/

January 23, 04h

Let me know what results you get, after your testing. I’d be particularly interested to hear if how it fares on a Mac (I only have Win machines). Anyway, glad to hear it’s a potential solution. I’m off…

January 23, 04h

well, since the right margin is set to negative, that means it will pull away from the right side by that many pixels, in effect creating a hole over there for the sidebar to sit in.

great solution.

seems to work in everything on this end.

January 23, 04h

wow… great solution indeed

Peter Zignego says:
January 23, 04h

Wow, I had been struggling with a problem similar to this with a layout I had been working on a few weeks ago, but I couldn’t figure anything out to make it work. A great bit of coding on your part Ryan!

Brian Warren says:
January 23, 04h

Looks good in panther - safari 1.1 - way to think outside the box Ryan.

January 23, 04h


January 23, 04h

My thoughts:
body {margin: 0; padding: 0;}
h1 {margin: 0;}
#content { border: 1px solid red; float: left;
margin-left: -250px; width: 100%; }
#content * { padding-left: 250px; }
#sidebar { border: 1px solid red; float: left; width: 200px; }
#footer { clear: both; }

Now, the “#content *” selector won’t work in IE. Then again, in IE, you can do
#content { border: 1px solid red; float: left;
margin-left: -250px; width: 100%; padding-left: 250px; }
because padding doesn’t count as part of the width like it does in the standard. So, with a bit of box model hacking, that might well be a solution.

Skid X says:
January 23, 04h

[ I’m italian, then sorry for my orrible english. ]

I think this solution:
and it appears to work well.
I’ve only added one div nested to #content.
I hope this may helps you.

megabassjosh says:
January 23, 04h

#main { width: 100%; }

#content {
float: left;
margin-right: 210px;
background: #eee;

#sidebar {
position:absolute; top: 0px; right:0px;
width: 200px;

#footer { clear: both; background: #ccc; }

This seems to work. The absolute positioning works because of the main div containing the #content and #sidebar divs.

tlack says:
January 23, 05h

Can anyone point me to a page describing how negative margins work? I didn’t understand the explanation above. Surely margin-right: -10px would have worked as well as -210px if we’re just creating a “hole” bigger than 200px..?

January 23, 06h

But can any one do it without wrapper divs? Eg, leave the structure exactly as in Dave’s post?

January 23, 08h

Try using expressions and display: table/table-cell.


Zelnox says:
January 23, 08h

To do it without the wrapper div, I think Jeremy and Josh already mentioned a possible solution above. I tried and got this:
1. Set #content width: something%
2. Remove margin-right (or at least reduce it to 10px)
3. Set #sidebar to float: left (float: right also works)

And as Josh said, if one resizes the browser to make it thin, the #sidebar will be pushed down. I chose float: left for the #sidebar, because it looks less strange if it did get pushed down from resizing. You can check it out at

Ryan’s method is more robust and probably looks better. ^_^

James F. Cerra says:
January 23, 08h

Here’s a slight modification to Ryan Brill’s trick, which removes the need for a container tag to be added:

body {
margin: 0;
padding: 0;

div {
padding: 4px;

h1 {
margin: 0;

#content {
float: left;
margin: 0 0 0 -208px;
padding: 0;

#content * {
margin: 0 0 0 208px;
padding: 2px;
background: #e6e;

#content * *, #content * * *, #content * * * * {
margin: 0;
padding: 0;
background: #e6e;

#content h1 {
padding: 0 2px;

#content p {
padding: .5em 2px;

#sidebar {
float: right;
width: 200px;
background: #ee6;
#footer {
clear: both;
background: #66e;

Technically, I (you) should use a child selector rather than a decendent selector, but I don’t think many old browsers (IE) support the former. That’s why I included the odd markup. I bet you (or I) could fix that with a dhtml behavior, however.

Hope that’s useful!

rick says:
January 23, 10h

Is there any way to get the sidebar on the left side? I’ve even tried a left and right sidebar, but it always ends with them both to the right of the content.

Hasan says:
January 24, 03h

How do you keep the two floats from overlapping in a narrow window with Ryan’s solution?

Lars says:
January 24, 04h


yes, there is a solution. Just change any margin-right to margin-left and exchange the floats (float:left to float:right, float:right to float:left). Would be a nice Javascript thing: Where would you want your sidebar?

Dave S. says:
January 24, 04h

Hasan - specifying a ‘min-width’ should work fine in non-IE browsers. Of course, since IE treats ‘width’ like ‘min-width’, a bit of custom filtering can make it play along too.

Hasan says:
January 24, 04h

Dave, thanks for the response, I’ve been looking to you for guidance in the 2 months I’ve started messing with web page building. Custom-filtering…you’re talking about hacks, right? This seems the crux of the matter…for non-commercial sights, shouldn’t the web communioty just start ignoring IE as much as possible? Your thoughts, please.

Manny says:
January 24, 06h

Anyone have any thoughts / ideas on how to get this to work with a three column layout where both the right column would be float:left and a static width and the right column would be float:right and static, width but the middle column would be liquid?

Matt says:
January 24, 06h

It’s situations like this that make me want to scream at my computer and give up on a pure CSS approach.

Dave thought about this one for months and still couldn’t crack it. In a professional environment, a developer building a site who is under pressure to hit a deadline is likely to say “Screw it, this should be simple but it isn’t” and resort to tables.

I have really developed a love-hate relationship with CSS lately.

tlack says:
January 24, 07h


Amen! Though I feel so dirty typing TABLE, I hate the way everyone at work looks at me when I spend four hours on a layout and get something equivalent to a 1996 site layout, but without the broad compatibility with older browsers.

Doh. If only I wasn’t so snobby.

January 24, 08h

Ryan Brill’s works is a fine solution ;-)
But change:
body { margin:0; padding:0; }
* { margin:0; padding:0; }
to avoid the gap on the top side in Mozilla.

In #footer add {margin-top:10px} for the gap between #footer and #container.(If you want ;-)

Niket says:
January 24, 09h

Is this what you are looking for:

Its easier to use “skip to contents” link rather than using content div at the top of the xhtml document.

Alicia Lane says:
January 24, 10h

Dave, what you described sounds a lot like something I did for one of my websites. I unfortunately have to run, so please forgive the lack of an in-depth analysis (and if I’ve misunderstood your request), but if you would like to see:

Positioning CSS is at

It seems to work great in all the browsers I tested via Browsercam.

January 25, 02h

Sounds like the solution works in most browsers that it could be expected to, as it uses CSS, eh? I was especially happy to hear about Mac compliance, as I couldn’t test on that platform. Good to hear.

January 25, 02h

I’ve been working on my mandatory “3-column box layout” the last couple of days, and the basic structure of it is about finished. When tested (IE,Opera & Firebird) it seems to be able to do what you desire.

It’s a work in progress, but if you (or anybody else) a’re interested, the current version can found at [ ]. As I’m no guru on the subject of css I make no guaranties of the code, but it does validate…

Oh, I nearly forgot to mention; It doesn’t look pretty! I haven’t styled it yet, just created a layout framework for future usage…

Freexe says:
January 25, 07h

This is great, I cant believe how well it works, plus you can use the same technique inside the content and get and another level.

Wow thanks so much for this. best solution ever, plus no more box hack

January 25, 08h

This is good stuff. I just implemented this solution on my page and so far it looks good, in Lynx, Safari, Mozilla Firebird (Mac), Opera,

It even looks passable in Netscape 4.7/Mac.

There are minor problems in IE5/Mac–the sidebar still appears below the main content–but I need to check the existing box model workarounds that I put into my stylesheet and verify that they’re all consistent with the new format.

January 26, 02h

Wow, i only just started to work with since i got sweared at using :P

Posts like these, really do help you out :D

Thanks Ryan! And the other “commenteers!”

January 26, 03h

I think I’m finally starting to understand the negative margins bit… since the margin specifies the space between the element and neighboring elements, a negative margin allows the neighboring element(s) to overlap into its own box space. Unconventional perhaps, but a great discovery.

January 26, 03h


this may be slight OT, but here’s a solution not using floats, but absolute positioning. Modified from code used all over. :-)

Basic structure ;

#wrapper {
/* contains all divs */

#leftmenu {

margin:0px 0px 0px 5px;
padding:10px 0px 0px 0px;


#content {
margin:0px 140px 0px 140px;
padding:10px 30px 40px 20px;
border-right:1px dashed #000;
border-left:1px dashed #000;
border-bottom:1px dashed 000;

#right {
padding:10px 0px 0px 0px;
margin:0px 5px 0px 0px;

January 26, 03h

Brian - thanks for your comment (#50). In one sentence you made the negative margin issue clear and obvious. Bravo!

Meanwhile… I’m with Evan (#5). Tables are SOOO much easier. Well, until you try viewing your page on a Palm Pilot, I guess…

Kris says:
January 26, 09h

Ryan’s method works fine in Safari 1.0 (OS10.2.8) too. Permanently bookmarked to learn from.

January 26, 10h

Does this meet the requirements?
#header {clear: both; background: #ccc;}
#container {position: relative;}
#content {float: left; background: #eee; margin-right: 210px;}
#sidebar {position: absolute; right: 0; top: 0; width: 200px;}
#footer {clear: both; background: #ccc;}

January 26, 10h

Sorry last one doesn’t work in IE (sidebar disappears) and float on content div is unnecessary anyway.

Can someone clarify this requirement?
“Floating, and not absolute positioning is necessary for the sake of a clearing footer.”

Dave S. says:
January 26, 10h

Will – cut the number of paragraphs in #content to one, and add the four you removed to #sidebar. Then refresh. You’ll understand as soon as you see it. :)

January 26, 11h

Ryan’s solution is quite brilliant. And Brian’s explanation (comment#50) helps explain why it works. I was scratching my head on this one for a while.

Keep in mind (as Tantek just helped me understand) that negative margins will only have this affect of allowing “neighboring elements to overlap into its own box space” on *inline* and *floated* elements. Remove the float on #container, and this solution will stop working.

In trying to make sense of why the solution worked, I came to the conclusion that margins only affect the width of non-floated block-level elements. But margins *won’t* affect the width of inline or floated elements. Rather, they’ll merely affect the *position* of the inline/floated element, and the position of other surrounding elements.

For inline/floated elements, a positive margin pushes elements away form each other, a 0 margin allows them to touch, and a negative margin allows them to overlap each other.

For traditional block-level elements, where margins *will* affect width, negative left or right margins have the effect of adding on to content width. Thus negative margins are probably an under-utilized trick for combining fixed and relative measurements when working with CSS layouts.

Ok, I’m done publicly explaining to myself. Hopefully others will benefit.

January 26, 11h

Now it makes sense!
After playing with Ryan’s solution for a while I’m still confused by the negative margin.
I can see how positioning can’t seem to solve the problem because it removes the positioned elements from the flow and thus the footer moves up.

Joshua Hore says:
January 26, 12h

Manny said: “Anyone have any thoughts / ideas on how to get this to work with a three column layout where both the right column would be float:left and a static width and the right column would be float:right and static, width but the middle column would be liquid?”

Freexe said: “… you can use the same technique inside the content and get and another level.”

Ta-da! (The extra divs start to add up, though.)

January 26, 12h

Ryan’s solution is great! Still doesn’t solve the problem of getting columns with backgrounds extending to the bottom; however, this is definately one for this amature designer’s toolbox. One does need to remember the additional margins when using this method recursively.

body {
min-width: 620px;
#container1 {
width: 100%; /* I discovered through trial & error that this is required for both containers */
float: left;
margin-right: -210px;
#container2 {
width: 100%;
float: right;
margin-right: 210px;
margin-left: -420px;
#content {
margin-left: 420px;
background: #eee;
#left {
width: 200px;
float: left;
#right {
width: 200px;
float: right;
#footer {
clear: both;
background: #ccc;

#container1 goes around #container2 and #left. #container2 holds #content. #right follows container1. #footer is last (of course).

January 27, 03h

Backgrounds to bottom:
With 1 more wrapper DIV it is easy (and a clearer DIV after the the nav DIV)

Attach the content background to this new wrapper and attach the navigation background-image to the negaiv margin wrapper and the navigaton DIV too!

If the Navigation is longer then the content the nav DIV’s background will be visible if the content is longer then the negativ margins wrapper DIV background will be visible.

January 28, 01h

Doug, you just made my day… ;) Also, your explination was quite good. Due to my being gone, I haven’t been able to keep up with all the comments as I would have liked… Ah well.

Scott, read Dan Cederholm’s recent article at ALA: - that should be what you need. I use that technique on my personal site.

January 28, 09h

Doug, thanks for publicly explaining the negative margin to us - explaining to others ‘s the best way to learn isn’t it?

Brian’s observation that a ‘negative margin allows the neighboring element(s) to overlap into its own box space’ can be illustrated with Ryan’s solution by removing the ‘margin-right: 210px;’ from the #content style.

Doing this makes the sidebar sit on top of the content. Seeing that helped it all click into place for me.

January 28, 10h

Regarding “Backgrounds to bottom” comment, I have a similar curiosity.

In my case, the sidebar may be taller than the content and I want the area above the footer to be white, with the area under the footer to be another color (the body’s background color). However, with the current design, the background color of the body will show through the space not occupied by the content, since the content is not as tall as the sidebar.

I would love to hear a better solution, but mine involves wrapping the content and the sidebar divs in a wrapper div whose background is set to white and height to auto. While this solves the problem in IE, Netscape does not extend the background of the wrapper div as I would like, so I had to use a fixed min-height to do that.

Any suggestions on a better solution that works well with Netscape?

January 28, 11h

[div id=”wrapper”]
[div id=”negativmargin”]
[div id=”content”]


[div id=”sidebar”][/div]

[div style=”clear:both”][/div]

The div with style=”clear:both” will constrain the wrapper to becaome enough high.
Explained here:

January 29, 07h

If someone need min/max-widths to to work x-browser (including IE), check out this technique developed by Svend Tofte:

February 12, 01h


I tried out your three column solution (post 42), and found I had to adjust the right margin on #container2 to 105px (half) to get it to center and allow #left to move up to the top of #container1.
This was on IE5.5/Win; is it just another IE thing? (If so, Tantek’s Hack would be in place here).

Matthew says:
February 12, 03h

On your first point, it appears to be a bug in Firefox/Mozilla (if I’m reading it correctly) - (agreement and some good examples come towards the end, as always :) ) - the clear on the footer should be enough to clear the sidebar (Opera is *my* “decent browser”, and gets it right ;-) ). And changing the margin to 199.9px causes weird problems here at particular browser widths in FireFox.

Your second point is very true; I would probably be using this in situations with no background on the main content and/or always enough content. :)

Matthew says:
February 12, 10h

I believe I’ve come up with a solution similar to Ryan’s, but that doesn’t involve a container div. That’s enough for Firebird and Opera, but IE needs an extra br to avoid a background-color bug (if the footer doesn’t need a background colour, I think you can miss even that out).

All I did to Dave’s original code is add margin-left: -200px; to #sidebar. has an example, tried in IE6, Opera7, Firebird.

February 12, 11h

Matthew, it’s great to see people trying to expand on the negative margins concept - that’s exactly what I was hoping would happen. However, there are a few things that need to be taken into consideration with the method you posted above.

1. The footer will no longer clear the sidebar (in decent browsers, such as Mozilla Firefox). However, this can easily be fixed by changing the margin-left to -199.9px.

2. Since there is no width set on the content div, it will only take up the width of the content it contains. If you were to delete most of the mock latin, you will see what I mean. Also, (slowly) resize your browser, and you’ll see the size of the content div shift around, as your text moves.

February 19, 12h

..nice thread. I have also a solution with negative margin.
Look at my site My solution has backrounds from header to footer but not with content first. I think that is not posible with a 3 column layout without javaScript. The solutions here in the tread (3 column) works not with IE. But the solution for a two column layout without extra div is great.

March 17, 12h

I just saw, that my WebSite is not accesible from this point. So use the link without the dot at the end. I hope I will get some featback.

Cory says:
March 19, 03h

I’m going to go out on a limb here, as this subject has been driving me crazy for quite some time and I’m far from a CSS expert. I understand the concept of CSS and the need for separating content from structure, but I’ve been trying to understand why it’s frowned upon to use tables to layout a page. Now, I’m not talking about 100% table-based layout; just the overall structure of a page like what is desired in this topic. It seems to me that the time spent getting the CSS to work in all browsers on all platforms is probably close to the same as modifying a table-based layout each time a major structure change is needed. I am willing to accept the fact I may be way off here, but I’m hoping that by posting this comment, someone can explain to me the pro’s and con’s of laying out a site using tables.

Joseph says:
March 20, 05h

Cory, the argument against using tables for layout is that it is not semantically valid to do so.

(This is the long answer; scroll to the last paragraph for the more concise answer.)

A web page is semantically valid if each element is being used for it’s intended purpose. ie, <p> tags contain paragraphs, <blockquote> tags contain long quotations, and <table> tags contain tabular data, et cetera. Tabular data is, you know, spreadsheet-type stuff.

Separating content from design, as you noted, is the chief benefit of CSS for the web designer. You can do that without being at all semantically correct. CSS doesn’t care if you’re using divs for your paragraphs, blockquotes for your lists, or tables for your compositing.

Being semantically correct really only has trivial benefits for the web designer – they can quickly read and understand their html when they need to refer to it. But to the site content creator, it has huge advantages: their content, which actually describes its structure with tags, becomes infinitely reusable. It can move from one system of content management to another without headaches. It can become a PDF, it can become a text-to-speech audio file, it can be syndicated via RSS or Atom, etc, etc. This is because semantic validity makes it infinitely easier for software to understand your page. Markup, ideally, is the process of making documents intended for humans comprehensible to machines as well.

The better a piece of software can understand your page, the more it can do with it. The immediate ramifications of this may not be obvious, but consider the case of the Googlebot. That is a piece of software that is designed to try to understand web pages, however limited it might be in that. If your page is semantically valid, Googlebot will understand it better, leading to more accurate search results for your site. This is a trivial example, but this is the general direction the web is moving, and the next stage in the evolution of the web is commonly touted as the “Semantic Web”, where machines automatically perform more of the tasks we are accustomed to doing manually through dumb browsers. Read this article by Tim Berners-Lee on the subject if you’re interested:

So that’s the long answer. The short answer is that, given the unfortunate layout discrepancies between the major browsers, at this stage only misguided purists would frown upon the occasional use of tables for layout. But if you’re creating tag soup, you’re just making your life (and Googlebot’s) unnecessarily difficult. Set your doctype to XHTML Transitional and use a table by all means, but don’t nest them: that way lies madness.

March 28, 06h

In thread number 63, I sad that it is not possible to make a 3 column layout with content first.
But this weekend a played with me old cascading style sheet and get a solution for a
three column float layout with content first. You may have a look at my site there I have implement the layout in my front-page.
The left column has a with of 12em and the right column a width of 30% . So the whole layout is fluid and you can change the font-size in IE to largest without having the layout to crash. It doesn’t matter which column is the longest; the footer is always on the bottom of the page over all three columns.
I have called the layout ‘Three column fluid madness’.
There are still some bugs in IE5, but I think I will fix them.
I have split the layout in position.css and style.css so one can look at the position layout. There are some unnecessary divs for the three column layout, but they belong to my page layout. The layout is not perfect, but I’m surprised how good it works in modern browser

Sam Wilkin says:
April 21, 12h

If anyone can demonstrate a version with a fixed-width left column (links), and a variable right column (content), as always with a clearing footer, it would be greatly appreciated.

The change-margins left-right and floats left-right doesn’t seem to work (suggested in reply 27).

Setting the fixed-width left column (links) to a negative margin works on IE. In fact, one doesn’t even need a container – set the left column (links) to negative margin, and the right column to an equal positive margin (content).

But on other browsers, if this is done the footer will only clear the right column (content). In other words, if the links column is longer than content column, it won’t work. This is true whether the original container strategy is used or not. It is even true if another floating container is put around all the columns.

Essentially, a negative-margined fixed-width column works on IE, but on other browsers, it simply ceases to exist. Even though it’s there, the “clear” setting doesn’t cause the footer to clear it.

Maybe I’m making some elementary mistake?

For now, back to tables…