TV version (Display Regular Site)

Skip to: Navigation | Content | Sidebar | Footer


Weblog Entry

How to Conceive a Layout

December 16, 2003

I don’t normally respond to CSS help requests, instead referring the asker to the css-discuss mailing list. It’s mainly a time issue, but I’m also of the opinion that you can’t learn if you have someone else doing it for you. I’ve never been one to ask for help if I could figure it out for myself. With Google and a few good books, I believe everyone can figure out CSS. It’s not easy, it takes time, but it is do-able.

But the other afternoon I got involved in a dialogue and decided to answer a few questions anyway. Here’s a patched-together result, which is very basic and easy to take for granted once you’ve learned it (and of limited use to most who read this site), but incredibly difficult to figure out if you haven’t.


How do you build a dual-column layout?

There’s no mechanism to do this specifically today. CSS-2 tables would be great, if you could use them. Unfortunately, you can’t thanks to current browser support.

So the method is to hack. And hacks are just that: they work, but they’re not the best solution. The following explanation will [hopefully] make sense, but it will sound ridiculous and over-wrought. Rightfully so, but we still have to compromise to make things work.

Your XHTML would, logically, look like this:

<div id="topBar">
  logo and whatever
</div>
<div id="sideBar">
  navigation
</div>
<div id="contentArea">
  content
</div>

The first thing to do is address the top bar.

#topBar {
}

That piece of CSS corresponds directly with <div id="topBar">, since ‘#’ is the symbol for an id. Similarily, if I’d used class="topBar" then I could use .topBar in the CSS, as classes are symbolized by periods.

Next, to assign a height:

#topBar {
  height: 100px;
}

Inches and centimetres aren’t very useful on-screen. Pixels, symbolized by px, are better for this sort of thing. To give it a background color:

#topBar {
  height: 100px;
  background-color: #991122;
}

The sidebar is pretty easy too. Instead of giving it a height, you’d assign a width:

#sideBar {
  width: 200px;
  background-color: #996600;
}

The tricky part now is the content. Since the sidebar is on the left, the best way to bring the content area up beside it is to pull the sidebar out of the document flow.

What does this mean? An HTML document is structured linearly, and by default all elements will display in the same order as they are listed in the markup. It’s very rare that you’d want to leave the elements displaying this way, so there are tricks involving absolute positioning and float that allow you to do something about it.

The trick is to remember that when you remove an item from the flow, any influence it had on the position of other elements disappears. Which means that in this case, we need to rig a layout where #sideBar won’t influence #contentArea’s position.

#sideBar {
  width: 200px;
  background-color: #996600;
  float: left;
}

You’ll see at this point that #contentArea will overlap #sideBar. This is expected, since #sideBar no longer affects #contentArea’s position. So how do we stop that? A pretty simple fix: push #contentArea over to the right by the exact width of #sideBar:

#contentArea {
  margin-left: 200px;
  background-color: #FFDDAA;
}

And there you have it, a two-column layout with a header. See how it comes together on this sample page. There are issues with this layout, particularily a) if you want to add a footer, and b) if you want to assign a background colour to either column that extends the length of the page, instead of the length of the column’s content. There are ways to do both. Perhaps a follow-up will come later that explores these methods; I have a working layout that does both at once, and isn’t dependent on the content size of either column. I’ll try to pare that down to the basics and explore it sooner or later.


Reader Comments

Niket says:
December 16, 01h

Dave,
I am no way near the expert in CSS that you and visitors to this site are. However, its been my experience while helping people at Webdeveloper forums (http://forums.webdeveloper.com/ ) that absolute-positioned layouts are easier to comprehend than floats. If this is intended to be “first lesson”, absolute positioned sideBar is a better choice.

Dave S. says:
December 16, 01h

Interesting point, I’ve heard it said that floats are tricky to wrap your mind around.

In this case, the difference between float: left; and position: absolute; left: 0; is pretty much nil. Same end result. I prefer floats for layouts, because it’s possible to clear them later for the benefit of a footer. You can’t do that with absolute.

Still, for the sake of raw comprehension, maybe I should revise that. Thanks for bringing it up, Niket.

Sean Sieg says:
December 16, 01h

There definately are two different mindsets about doing two or even three column layouts: the floating way, and the absolute way. Just like Perl, there’s more than one way to accomplish an end.

Personally, I fall into the float camp, and I had just redone my two and three column layouts with the approach presented here (I had been floating both my content and menu before), and was planning on writing a similar entry. Now, I’ll just link to this one! Good article.

Oh, and I do agree about the teaching floating comment. I am in the process of writing some beginner’s documentation for our own Web Dev site to help students create basic templates, and explaining floats can be a real pain.

Dris says:
December 16, 02h

I believe Eric Meyer wrote an article on floats that really cleared things up. [url - http://www.complexspiral.com/publications/containing-floats/ - added by DS]

As far as extending both columns, I used a technique that extends my site’s sidebar (though not the main content, as it’s usually longer; usually). However, I had to hide it from Internet Explorer, due to a weird rendering bug in which the background image would overlap the text at an arbitrary point. I’ll fix it eventually (when I go about cleaning up the code), but I’m leaving it as-is for now.

Magnus says:
December 16, 02h

I have always floated both the content and the side-bar inside another div, but this way looks much better.

December 16, 02h

Are there any advantages of floating the sidebar rather than floating the content? (ALA-style) Or is it just personal preference?

It would seem that floating the content would be useful if you wanted a sidebar that extended all the way down, and your content was always longer than your sidebar, but there may be other ways to accomplish the same thing.

December 16, 02h

The method as stated has a problem, which is this: once you’ve got your columns, the next thing you’ll want is to give them margins (more strictly padding, but beginners would call them margins). This method falls apart right there, at least on IE5+ and IE6 without the right DOCTYPE. (Do I really need to add a link to the ALA article here? I think not!) After much fiddling, I think the only reliable method is the double-DIV: every section has an outer DIV to apply overall width to and an inner DIV or other block-level element to apply padding and margins to. I’ve got a silly little tool for generating arbitrarily complex double-DIV layouts at http://flurf.net/boxy/ if you’re interested; it’s kludgey, but what the hell.

Of course, this is just the start. Eventually the DIVs will multiply, and before you know it…

Three DIVs for the design-gods painting on Macs,
Seven for the usability-lords in their websites of grey,
Nine for Windoze geeks doomed to debug,
One for the Zeld Man on his orange page,
In the land of New York where the pundits cry.
One DIV to size them all, One DIV to pad them,
One DIV to colour them all and in the browser style them
In the land of W3 where the standards lie.

Lenny says:
December 16, 02h

When I first learned how to make site layouts with CSS I looked at the W3C’s homepage (http://www.w3.org/.) They float every column and place a cleared element after the columnar section. I continue to use this technique for most designs I make.

Lenny says:
December 16, 03h

Eric: IE has a “standard-compliancer mode” (I know, I know) explained at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnie60/html/cssenhancements.asp. If you define a doctype and do not put an xml declaration, ie 6 will fix the box model.

December 16, 03h

Lenny - that’s what I meant by “at least on IE5+ and IE6 without the right DOCTYPE”. Unfortunately, the DOCTYPE doesn’t help on IE5+, which is why you need a fudge factor. My method does this:

* apply a 3% fudge factor for the benefit of IE5, hiding it using * html so the other browsers don’t choke;

* apply a 0.1% fudge factor for IE6 to prevent the flicker you get when resizing, hiding it from other browsers using * html, and from IE5 using the backslash hack (w\idth: …);

* include an empty <div class=”enclose”></div> (the style is enclose { clear: both; }) inside any floated DIVs that contains other floated DIVs, to force compliant browsers to enclose them properly (IE already encloses them anyway, which is the Wrong Thing);

* apply percentage widths to outer DIVs and padding/margins/borders to inner ones.

See why I wrote a program to automate it? It’s a pain.

(By the way… another pain is that this blog’s commenting system doesn’t convert < to &lt; automagically; makes it hard to discuss HTML, you know…)

Lenny says:
December 16, 04h

My mistake, Eric. Your method is a bit too hacky for my taste and relies on browsers having two bugs simultaneously, one to initiate the hack and the other to be fixed.

(Dave, can you fix the URLs in my posts to remove the punctuation from the end?)

December 16, 05h

That’s the beauty of IE, of course: you can ALWAYS rely on it to have simultaneous bugs…

I agree it’s hacky, but with >80% of the world using IE, what’s the option? At least the hacks can be isolated.

Lach says:
December 16, 08h

I maintain that the only way to learn to do a good CSS layout, is to produce at least 5 bloody awful ones.

Alex says:
December 16, 09h

My website uses tables (don’t laugh, I’m changing it soon) but I have made many expirmental CSS layouts. I prefer the float way shown in this post. I seems more… logical. Ok, no it doesn’t. I take that back. But, it just… ARG. It’s less work? I dunno why I like it. But I do.

kami says:
December 16, 10h

My solution was to use floats; because the sidebar column wouldn’t stretch all the way to the footer, I cheated with a couple of background images.

http://zenaku.net/css/800/left.css
http://zenaku.net/css/800/right.css

dusoft says:
December 17, 01h


Uff, Eric, the box code generator is very nice indeed (maybe little help on how to create the template schema (I found that you have to set proper align (3 spaces?) by myself). But it’s quite obscure - reminding me nested tables - now don’t really want to use so many nested divs or we are back where we started.


Otherwise it is very good to see such a thing in action (php/xslt).

Tim says:
December 17, 04h

Well, I have to say that Mr. Shea’s explaination of floating is one of the clearest that I’ve read.

I’ve been poking around the various css web resources and have fiddled with my pages using a float variation. But I have never been really clear on why float did what it did. Now I get it. Thanks Dave.

(I really hope I get all those css books on my Xmas list so everything else becomes clearer.)

18
tq says:
December 17, 05h

I tend to use this http://www.csscreator.com/version2/pagelayout.php to create a layout because it uses floats and a clear for the footer if you specify it.

19
Michael Pierce says:
December 17, 08h

Thanks for the reminder on floating the sidebar, Dave. I had forgotten about that on my layout and was struggling with footers, etc.

I tend to do fairly well with the mechanics of CSS and even comprehend most of the hacks/workarounds. The biggest thing I struggle with, however, is the design aspect of creating a site. How do I best present information? How on earth do I come up with a reasonable color scheme…seems like I’m always inventing colors for things on the fly rather than having a coherent plan for them. I’m an old programmer and, obviously, not a graphic design person. Any suggestions on places I can go to learn design rather than CSS mechanics?

Unfortunately, I seem to be stuck in a world where I know good design when I see it, but flounder horribly when faced with a blank page….

20
David House says:
December 17, 10h

>So how do we stop that? A pretty simple fix: push #contentArea over to the right by the exact width of #sideBar:

Or you just float: left; the content as well.

s t e f says:
December 17, 12h

To all who’ve commented about the difficulty of explaining floats: I’ve had the same and found that teaching through a parallel with old [img align=’left’] markup helps a lot.

I show how a [img align=’left’] has text wrap around it, then I move to a small div that does the same with a float.

And then I add a margin for the sake of presentation and voila.

Sean Sieg says:
December 18, 06h

Michael, here’s a link that might help you get a color scheme slapped together. It’s a quickfix, and if you want something more robust, you probably want to learn Photoshop.

Eric Meyer’s Color Blender
http://www.meyerweb.com/eric/tools/color-blend/

December 18, 10h

Finally, a clear enough explanation of creating a basic table-less column layout that I broke down at last and did it to my own site at http://www.penmachine.com – and it worked on the first try. Thanks, Dave.

The initial table-removing only took five minutes, but of course all the tweaking I had to do to get things working the way I like it took some time more.

One thing I wonder: if you create a right-hand sidebar with a float: right, is there really any need to have a separate div for the main body content? I used one, but it should work just as well without.

Ben Nolan says:
December 19, 05h

I made a little tool for creating 3 column layouts. It too uses absolute positioning - though having read that eric meyer article I might have a play around making some floating layouts.

http://www.ripcord.co.nz/projects/cssdesigner/

Ben

25
kliertje says:
December 20, 12h

I dont need double divs. In Eric Meyer on CSS by guess who, he recomends padding and margins 0 and to add padding to all the elements inside the div. EG: a div with id content could then have one encompassing rule
div#content {padding:0; margin: 0;}
div#content h1, h2, h3, p, ul, li, img {padding:0 1em; margin: 0;}
This works around the padding debacle of IE.

26
Lance says:
December 29, 07h

Michael Pierce:

I’m in a similar situation. I’m a nuts and bolts guy. I’ve read good things about “The Non-Designer’s Design Book” by Robin Williams (ISBN 0321193857). It’s around $11. I’m planning on getting it and tackling my psuedo-fear of visual design.

Amy says:
December 29, 08h

I’ve just been trying to come up with a solution to the problem Dave S. mentions in “b) if you want to assign a background colour to either column that extends the length of the page, instead of the length of the columnís content.”

The CSS Creator (http://csscreator.com/version2/pagelayout.php) uses an outer div border color, negative margins trick to create column background colors - but that doesn’t work if you want your columns to use background images. I’ve to decide to use a background image on my outer div - that’s probably what kami was doing. It won’t work for a liquid layout, though. I’m still looking for a smarter solution.

Dave, I was surprised that you mentioned using tables for a dual-column layout. Isn’t that semantically incorrect? Or am I missing something?

Andri says:
January 23, 04h

Iím having a problem when I use a fixed width on the content area … for some reason IE adds a 3px space to the right of the sidebar and pushes the content area to the side. I can’t seem to solve this with out adding some extra <div> or switching the content <div> to absolute positioned.

Dave S. says:
January 23, 04h

Andri – sounds like the old IE 3px bug flaring up:

http://www.positioniseverything.net/explorer/threepxtest.html

30
Stephanie says:
May 13, 07h

I’m trying to do a two column layout with a header and footer. I did have this layout with the left column floated. Although there seemed to be a problem when needing to clear elements in the right column. If a clear:left was needed in the right column it would clear the entire left column. So, I now have the left column with an absolute position so that I can clear the elements needed to be cleared in the right column. The problem is, sometimes the content in the left is longer than the content in the right column. When this happens the footer cuts through the left column. Have you seen this problem before? How did you fix it if you have?

June 10, 04h

Thanks for the lesson! I had missed the importance of the margin-right setting for ensuring that the body doesn’t encroach on the sidebar. I’m now a happy chap with Outlook stationery working as I want it!

Thanks :)

Chelle says:
July 01, 05h

Niket, I would have to disagree with you a little bit on the absolute postitioning being easier than float for beginners. I don’t know maybe I am different, But Ryan @ World One Web has been teaching me a ton of things with CSS that I didnt know, and encouraging me to use div tags instad of frames, etc. He taught me how to float them, if they dont work right, you try a clear: tag in your style sheet, it almost always fixes the problem. I donbt know maybe its just me, but I caught on really quick to the float, I HATE POSITIONING!. lol

chelle says:
July 01, 05h

I have a reccomendation to all of you out there who need help with color schemes, this site takes one color that you like you. You enter it in hexadecimal and it returns at least 4 matches. These colors just flow together I love this site! http://www.stylephreak.com/index.php/archives/2004/05/the-ultimate-color-scheme-generator/
By the way, anyone who looks at my site, lol dont judge, its the worst layout, and its coming down..should be this week, just been busy with work. heh