Fixed or fluid width? Elastic!

A question many web designers ask themselves each time they start working on a new project is whether the site should use fixed or fluid width. The debates on the subject are many and sometimes heated. This is not one more of those debates.

Instead I'll explain how I combined some of the benefits of both fixed and fluid layouts when redesigning this site. The result is an elastic width layout, a concept which is not unique -- you may recognise the term Elastic Design from Patrick Griffiths' A List Apart article by that name.

For the purpose of this quick explanation I'm leaving out the header, navigation, and footer areas of the HTML structure, focusing on the remaining two column layout which consists of the #main and #sidebar div elements:

  1. <div id="wrap">
  2. <div id="main"></div>
  3. <div id="sidebar"></div>
  4. </div>

To create the two columns I've assigned widths to the two elements and floated them in opposite directions:

  1. #main {
  2. float:left;
  3. width:59%;
  4. }
  5. #sidebar {
  6. float:right;
  7. width:29%;
  8. }

The widths are set in percent to make both columns expand and contract as the browser window is resized.

To get some spacing between the outer edges of the columns and the edges of the main layout container (#wrap) I've given each column a little bit of margin. This is also specified in percent to make the margins flexible and to make it possible to accurately calculate the total width of the two columns plus their margins.

The flexible margins are what Richard Rutter referred to as "concertina padding" in a comment on my post about the redesign.

  1. #main {
  2. float:left;
  3. width:59%;
  4. margin:0 0 0 4%;
  5. }
  6. #sidebar {
  7. float:right;
  8. width:29%;
  9. margin:0 2% 0 0;
  10. }

That's it for the column widths and margins. The layout width is now fully fluid, which can cause readability problems for people who like to make their browser windows very wide since lines of text become too long to read comfortably.

To avoid that I used the max-width CSS property to specify how wide the #wrap element can become. I could have used pixels to define a maximum width for the layout, but that would have made line lengths increase as text size is reduced and decrease as text is made larger. I wanted line length to be comfortable for reading and stay roughly the same regardless of text size. By using em instead of px as the unit for max-width, the width will depend on font size and line length will be similar no matter what size the text is.

  1. #wrap {
  2. max-width:70em;
  3. }

Then I added a couple of other declarations that may be of interest to that rule. One centres the layout horizontally, and the other inserts a vertically repeating background image to serve as a separator between the columns:

  1. #wrap {
  2. margin:0 auto;
  3. max-width:70em;
  4. background:#fff url(/i/separator.gif) repeat-y 67% 0;
  5. }

That's it. In case you're wondering why I didn't use the min-width property to prevent the layout from becoming too narrow, it's because I can't really see a reason to. Why force people who prefer very narrow browser windows to deal with a horizontal scrollbar? Yes, the navbar will wrap in very narrow windows, but so what?

Oh, right. Just one more thing. Internet Explorer for Windows.

IE doesn't support max-width, so I needed to find a workaround for that. I chose to use an expression, Microsoft's proprietary CSS extension. Since expression is invalid CSS and I want my main CSS file to be valid, I put the IE stuff in a separate file and used conditional comments to make sure only IE loads the file. I also put a couple of additional fixes to take care of the IE Doubled Float-Margin Bug in the IE-specific CSS file.

  1. #wrap {
  2. width:expression(document.body.clientWidth > 900? "900px" : "auto");
  3. }
  4. #main {
  5. display:inline;
  6. }
  7. #sidebar {
  8. display:inline;
  9. }

The #wrap rule makes the width of #wrap flexible until the browser window is wider than 900px, at which point the width of #wrap is fixed at 900px. Unfortunately for IE users, this will not make the width elastic, just fluid with a maximum width. Not as neat as in modern browsers, but better than nothing.

And there you have it: elastic width with concertina padding and a maximum width. Feel free to adjust it to suit your needs.

Update: Since I wrote this article I have redesigned the site, so the CSS described here does not match what I actually use anymore.

Posted on April 25, 2005 in Usability, CSS