Musings about Coding, Business and other Geek Stuff Live and Direct from somewhere on the planet
February 24, 2005
CSS tips for coders: The only layout rule you need to know

In this second part of my informal series of articles about Cascading Style Sheets for coders, I will cover probably the most frustrating thing with regards to CSS that most of us come up against, which is page layout.

Note I am writing and updating this at the moment. It is incomplete, but will remove this message when done.

Many websites and in particular blogs have multi column layouts. If you google multi column layouts you will find many recipes that are easy to include in your web application. Before I always found one of these and used it to layout my pages. However I was almost never happy. Why?

  • If I resized the page, things wouldn’t always look right. Boxes would move around in strange positions or would overlap.
  • The real content of the page such as the blog article would in most cases come at the end of the page if viewed in a non css browser such as lynx or mobile browsers.
  • Adjusting these to my own layouts where always trial and error. Nothing just worked.
  • It all seemed like a giant hack

Float and it’s problems

The problem that causes this is that the majority of css multicolumn layouts rely on the css float property to do its magic.

It turns out that this is a big conceptual error. Read what the above CSS1 standard says about float:

Using the ‘float’ property, an element can be declared to be outside the normal flow of elements and is then formatted as a block-level element. For example, by setting the ‘float’ property of an image to ‘left’, the image is moved to the left until the margin, padding or border of another block-level element is reached. The normal flow will wrap around on the right side. The margins, borders and padding of the element itself will be honored, and the margins never collapse with the margins of adjacent elements.

In otherwords it is designed for images and other elements that you want to float to the left or right of some content. It has a ton of rules to use and it is normal to experience the annoying collapsing side effects, because you essentially hand over control to the browser about what to do when the browser resizes.

Headline

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam non nisl vitae arcu consequat volutpat. Aliquam diam. Sed libero. Suspendisse porta risus non lectus. Vivamus sed justo eget lorem varius iaculis. Fusce hendrerit rhoncus ante. Donec rhoncus wisi. Nullam dignissim wisi in est. In in wisi in magna varius ultricies. Maecenas euismod lectus vitae augue. Cras ullamcorper molestie felis. Duis wisi. Aenean feugiat, ante ut pretium scelerisque, lorem libero commodo mauris, sit amet tristique arcu orci aliquet sapien.
  • We like to link
  • We like to link
  • We like to link
  • We like to link
  • We like to link


The source of the css is:

.head {
     font-size:1.2em;
}
.content {
    float:left;
    width:60%;
   background:#FFE;
}
.rightcol {
   background:#EEF;
   margin: 2px;
   float:right;
   width:35%;
}

And the html:

<h1 class="head">Headline</h1>
<div class="content">
Lorem ipsum dolor sit amet...
</div>
<div class="rightcol">
<ul>
<li>We like to link</li>
<li>We like to link</li>
.....
</ul>
</div>

This can become very flaky when using it with resizable pages and is generally a pain to debug. One of the worst things as well is that there is much trial and error in making it look good. However as all the browsers are different, it again is almost impossible to get right.

When to use float

Float is very powerful, but not for multicolumn layouts. You should use float for example for wrapping text around an image. Also use it in controlled areas where a bunch of similar items need to be layed out automagically. For example most CSS list based navigation bars and in my own SoapBX where I automatically flow the presentation previews. Try resizing the browser on that screen or resizing it.

Absolute positioning to the rescue

Absolute positioning is just about the coolest and most obvious feature of CSS that you hardly ever hear about.. With this you can control exactly where you want things on a page.

The thing about absolute positioning is that it isn’t quite as absolute as you might think, but that is actually a good thing. You might think absolute positioning would give you an xy grid for positioning, which it does. However it positions things relative to a box (by default the page). So you can position things 200 pixels to the left of the right side of the page Thus if you want a column at the right side of the page you could create a class like this:

.content {
   position:absolute;
   top:25px;
   left:0px;
   right:204px;
   background:#FFE;
}
.rightcol {
   position:absolute;
   top:25px;
   right:0px;
   width:196px;
}

Headline

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam non nisl vitae arcu consequat volutpat. Aliquam diam. Sed libero. Suspendisse porta risus non lectus. Vivamus sed justo eget lorem varius iaculis. Fusce hendrerit rhoncus ante. Donec rhoncus wisi. Nullam dignissim wisi in est. In in wisi in magna varius ultricies. Maecenas euismod lectus vitae augue. Cras ullamcorper molestie felis. Duis wisi. Aenean feugiat, ante ut pretium scelerisque, lorem libero commodo mauris, sit amet tristique arcu orci aliquet sapien.
  • We like to link
  • We like to link
  • We like to link
  • We like to link
  • We like to link

As you can see the positioning is a lot crisper and can still handle various kinds of dynamic sizing.

Still todo add section about relative positioning and proof read

Posted by pelleb at February 24, 2005 02:01 AM
This entry was posted in the following Categories: css
Comments

I just started playing with css sheets, and I'm running into a problem with centering. I've been using absolute positioning, but is there a way to center with absolute? If I were coding it, I would get screen size, widget size, divide each by 2 figure out center of the screen and subtract half the widget size to get the position to start from. But I'm at a loss for how to do it using css.

Posted by: Tim on March 9, 2005 10:15 AM

To center you should set the left and right attributes to the same.

If you have an item of an absolute width, you can set left and right to "auto", which should do the trick.

Posted by: Pelle on March 9, 2005 10:46 AM

A fine idea until you have sight-impaired readers, at which point your absolutes make it impossible for them to use the zoom features. If you must use absolutes, do your positioning with ems, not pxs.

Posted by: Elf M. Sternberg on March 10, 2005 11:56 AM

But how do you get around explicitly stating the height of the container div? In my experience and testing, positioning content and nav divs absolutely means that the container div won't stretch vertically with them.

The trick to floating (at least for 2-column) is to float only ONE: the navigation div. So you float it right, set the width to 200px and then set the margin-right on the content div to 200px. The effect is the same, and also the containing div wraps around both and stretches with them.

Posted by: Jason on March 11, 2005 09:43 AM

There is the slight problem with IE that if you set a left and right position without setting a width it ignores the right value ( the same for top and bottom with it ignoring the bottom value ). But abslute positioning can be very useful.

Posted by: Simon Proctor on March 14, 2005 05:55 AM

To whom made this page: have you looked at how your this page looks when resized and when viewed with IE vs Netscape or Firefox?

What you preach is not working.

Posted by: brodee on March 25, 2005 12:54 PM

Ugh. As others have already noted, the absolute positioning absolutely sucks. :-( :-)

I baked-in a lot of goodness (em-based, min & max width, etc.) into the CSS used for e.g., http://www.RetreatToTheSource.com/
View the source and the CSS for more and do all of the fun stuff like resize the window and zoom in and out on the various pages to see it all in action.

Posted by: John D. Mitchell on May 26, 2005 08:16 PM
Post a comment
Name:


Email Address:


URL:


Comments:


Remember info?