This is the celebrated journal of Mr. Simon Collison A.K.A Colly

Redesign Notes 1: Width-based layout

5th February 2006

Many folks have emailed me about the new layout I’m now sporting - specifically asking how the site resizes based upon the width of the browser window. It’s something I’m really pleased with, giving me what Inman refers to as my “superfluous third column”, and if your browser window is currently less than 990px wide, you can’t see it unless you scroll down. It’s a place for me to put the blogroll and less important stuff, and generally acts as an incentive to go wide as you browse.

Due to numerous requests, the fact that Cameron is continuing to investigate the possibilities, and also the similar implementation used by UX Mag, I figured it might be helpful to put this method into circulation as more of us wish to treat our pages this way.

The approach

Initially, I was hell-bent on making a perma-wide site, like Bearskin Rug or ALA, my naive brain thinking that as most of my users were viewing with at least a 1024 x 768 resolution, a fat site would be fine, until Jeremy pointed out that I was probably confusing screen resolution with window width. He was right of course. So what if the resolution is 1024 x 768 - that’s crap if most visitors have the browser at say 900px wide, ensuring they have a bit of desktop available as they browse. D’oh!

The mission
  1. To create a layout NOT based upon screen resolution, NOT forcing a horizontal scrollbar, NOT relying on cookies or a user choice to define a preferred layout.
  2. To create a layout that uses three columns, but remains fixed. That is, my column widths never change, and the site cannot be considered liquid or elastic.
  3. To create a layout that works semantically, and doesn’t compromise the flow of the document regardless of browser size.
  4. To create a layout option that still makes sense without JavaScript enabled.
The (X)HTML

Firstly, declare a wrapper ID immediately after body, but combine it with the class that declares your default page width. Note that during page load (depending on how much needs to be loaded) this class will be in effect until the JavaScript is actioned.

<div id="wrapper" class="mainwrapper">

Here I’m using class=“mainwrapper” as my default, meaning my pages will be 980px width during page load. I like it this way around, as it gives visitors a quick glimpse of the third column before hiding it if the window is too small.

The CSS

Nothing especially tricky here. Firstly, declare all the common values for your wrapper with the #wrapper selector, and then use the two classes to define the two possible page widths.

#wrapper {border: 1px solid #CCC;background: #FFF;}
.altwrapper {width:728px;}
.mainwrapper {width:980px;}

Naturally, anything else browser-width-dependent you wish to do with CSS can be declared in each class.

The JavaScript

The javaScript does three key tasks. Firstly, we ensure that the classes will still be swapped instantly even if the user resizes the browser after the page has loaded.  Next, we sniff the width of the browser, and define the width under which the class swaps should take place (in this case anything below 990px). Thanks to getElementById, we can then apply the function to a particular ID (#wrapper) and declare the class it should be combined with (.altwrapper) should the browser window be less than 990px. If the window is wider than 990px, .mainwrapper remains in place. Finally, the function is instructed to run.

Watch out for forced line-wraps, indicated by ***. Delete those and you’ll be fine:

wraphandler = {
  init: function() {
    if (!document.getElementById) return;
    // set up the appropriate wrapper
    wraphandler.setWrapper();
    // and make sure it gets set up again if you***
resize the window
    wraphandler.addEvent(window,"resize",***
wraphandler.setWrapper);
  },

  setWrapper: function() {
    // width stuff from ppk's
evolt.org/article/document_body_***
doctype_switching_and_more/17/30655/index.html
    var theWidth = 0;
    if (window.innerWidth) {
	theWidth = window.innerWidth
    } else if (document.documentElement &&
                document.documentElement.clientWidth) {
	theWidth = document.documentElement.clientWidth
    } else if (document.body) {
	theWidth = document.body.clientWidth
    }
    if (theWidth != 0) {
      if (theWidth < 990) {
        document.getElementById('wrapper').***
className = 'altwrapper';
      } else {
        document.getElementById('wrapper').***
className = 'mainwrapper';
      }
    }
  },

// addEvent stuff from John Resig's ejohn.org/***
projects/flexible-javascript-events
  addEvent: function( obj, type, fn ) {
    if ( obj.attachEvent ) {
      obj['e'+type+fn] = fn;
      obj[type+fn] = function(){obj['e'+type+fn]***
( window.event );}
      obj.attachEvent( 'on'+type, obj[type+fn] );
    } else {
      obj.addEventListener( type, fn, false );
    }
  }
}

wraphandler.addEvent(window,"load",***
wraphandler.init);
What I’m not telling you

Note on this site that the right column has a shaded block containing a bubble message made to emulate the look of the header across the other columns.

When the window is too small, and the right column wraps under the middle column, this block is removed, making the column appear to be a seamless, if a bit long, column.

It’s easy to do, and just involves some display:block and display:none action for that block alongside the other getElementById declarations. It must be quite easy to do, because I managed it.

Credits

As much as I struggled on in a world of my own with all sorts of crazy JavaScript methods and chaos, the final script would not have hit daylight were it not for the intervention and rambling idea-swapping of Britpackers Jeremy Keith, Mike Stenhouse, Drew McLellen, Patrick H Lauke and Tim Parkin, who all had a crack at this before genius Stuart Langridge stepped in, threw my attempts out of the window, and hit me with a near-perfect script. Good work, fellas.

Important credit also for the addEvent() JavaScript from John Resig. Apologies to John for missing the credit initially.

Use of this method

Feel free to implement this technique if you like it. But don’t copy the CSS outright, don’t hotlink to my JavaScript file, and link back to this tutorial in your JS for anyone else who wants to try it.

Responses

# Adrian Kostrubiak responded on 5th February 2006 with...

As I normally browse with a wide window, I didn’t notice this cool effect until it had been linked by Mr. Inman.  Instantly, I thought it was really cool.

Nice to see how you’ve implemented this so well.  Hopefully, sometime soon I’ll have a reason to use this cool technique on a site.

# Andy Hume responded on 5th February 2006 with...

It’s probably just me, but, why not make it liquid? I’ve never got to the bottom of why people are so hell-bent on creating static width layouts.

To quote JSM,

“I honestly don’t think liquid layouts are the last step in evolution for web layouts.”

Well, I actually think they possibly might be, when we remember the Dao.

For the record, their are now two sites in my feed reader (NetNewsWire) that I can’t see fully when following the feed to the post.

# Andy Hume responded on 5th February 2006 with...

Agh, sorry.

I must have messed up that link. Where was I…

A liquid layouts - the ultimate layout:

I actually think they might be, when we remember the Dao

For the record, their are now two sites in my feed reader (NetNewsWire) that I can’t see fully when following the feed to the post.

# Ben Ward responded on 5th February 2006 with...

I do like the effect, it’s a very neat trick and very important given how varied window-widths have become. I Think I sit somewhere around the 900px mark - maybe a little less on my 1024x768 iBook.

I may well go for something similar when I redo my site, though my aim will be to emulate the new CSS3 media queries as closely as possible. I have a feeling that they’re only supported in Opera so far, sadly.

I’m liking the redesign work so far Colly, keep it up.

# Simon Collison responded on 5th February 2006 with...

Andy: I agree with almost everything Allsop says in the ALA Dao of web design arrticle you linked to. In particular, I was drawn to this statement:

Using percentages (or other relative values) to specify page layout in CSS automatically creates adaptive pages. As browser windows widen and narrow, the layout of an element adapts to maintain the same proportions, and so the whole page layout adapts. Readers can choose the window size they find appropriate to their needs.

Surely the width-based layout I’m using does this (albeit in a different way). The layout of an element (my wrapper) does indeed adapt to the browser window. Also, most readers can choose the window size they find appropriate. Or even better, the layout is chosen for them. No resizing necessary.

The plus for me as the designer is that my need for pixel-perfection is not compromised, and as such I achieve the designer vs reader “enlightenment” Allsop talks so strongly of. I’m taking the piss out of myself there, by the way…

# Andy Hume responded on 5th February 2006 with...

I suspect you’re right - it is a good compromise between pixel perfection and the Dao.

I’m not a designer, so for me pixel perfection will always come second to the Dao. However, I’m not so stubborn as to dismiss your point that designers require a certain amount of control if they are to make the web all that it can be (is that enlightened enough for ya? ;))

I’m happy to lurk quietly with my prejudices. Just don’t expect me to notice the third column in my RSS reader. ;)

# eric responded on 5th February 2006 with...

This is an incredible trick, one I’ve wondered how to pull off since I saw it done in Mint and later at Shea’s Rosenfeld Media site. I’m one of the narrow-browser users, and I tend to still produce designs for a maximum of around 850px wide. This opens up the options a lot - it’s a great balance of fixed and fluid width design.

# Jesse responded on 5th February 2006 with...

I was toying with a couple layouts and couldn’t get this work… you just made my week ;)

# Ross responded on 5th February 2006 with...

Shift did it…

Note the “Related stories” et al boxes on the right. Do a resize and watch them appear down the bottom.

;)

# gareth responded on 5th February 2006 with...

I have something pretty similar on the go for a client at the moment, but actually using a liquid layout instead of a fixed one.

The grid is 50%/25%/25% for most of the site - the problem was that at lower resolutions the left most (content) column was getting a bit squashed. So it collapses to 75%/25% below about 850px - with the third column folding into the second.

The technique should hold for semi-elastic designs as well. Changing the text size of an element sized with em’s would change it’s width and the layout could adapt, even forming a zoom layout without the user having to do anything other than have much larger text?

# Simon Collison responded on 5th February 2006 with...

Eric, Ross: I’m not assuming this is a 100% new technique, as Dave did indeed do something similar with Rosenfeld media, and of course Mint does it too. I do like the fixed column width approach of this version though (similar to the Shift example and UX Mag.

I was keen to put out this version as many people want to know how it’s done, hence some transparency. Layout techniques are too important to keep to one’s self.

Gareth: I’d be very interested to see how this approach works with your percentages. Let me know when it’s done…

# eric responded on 6th February 2006 with...

Oh, no, I wasn’t suggesting you were taking a disproportionate amount of credit for this at all I’m just pleased as punch that someone wrote up how it was done!

Anyway, your version is functionally different; mint rearranges itself way more, with stuff looping around, and Rosenfeld is simply resizing the content without actually doing any rearranging.

# Ross responded on 6th February 2006 with...

Hehe, neither actually, I knew you weren’t trying to claim it, sorry should have been more clear.

Just wanted to point out other interesting examples. :)

# Tim responded on 6th February 2006 with...

Well done with the design…

... but hasn’t Stuart at http://www.muffinresearch.co.uk/ done it without Javascript at all?

# Simon Collison responded on 6th February 2006 with...

Eric, Ross: Sorry back - I wasn’t insinuating that you were insinuating…

Tim: I like Stuart’s approach, but for this technique I didn’t want percentage-based, flexible columns, I needed fixed-width columns. I also note that Stuart’s right column shrinks to literally a word’s width before forcing a scrollbar, which again is something I want to avoid (top design though Stuart)...

# Ivan Minic responded on 6th February 2006 with...

Very neat tutorial.. especially javascript part :)

# Tim responded on 6th February 2006 with...

Thanks for the reply Simon - it’s nice to know you read the comments! :)

Only the top part of Stuart’s right hand side shrinks (and I agree, I’d probably want to avoid that too). It was more what’s underneath (Flickr badge, category archive etc) that I was refering to.

# Stuart responded on 6th February 2006 with...

@Simon: Thanks for the compliments on my site design. Point taken regarding the re-sizable column. I’ve added a min-width to counter this.

@Tim: Thanks for pimping my site the cheque’s in the post ; )

The idea for my site was to try and create a design that went as far as possible to show all of the content for the given screen width whilst not requiring any javascript. Like you I also wanted fixed widths for my columns (albeit the column that goes across the other 3 which has to be flexible).

Looking at your layout I am wondering if you could achieve the same layout without the requirement for javascript? Not that there’s anything inherently wrong with using javascript in a degradable way but it’s certainly food for thought.

# Narayan responded on 7th February 2006 with...

Well done, Simon! I’m totally impressed that it even works in IE6/PC.

I’m a big fan of liquid layouts, which I think optimize the content (within reasonable parameters) to the browser window width. Unfortunately, they’re not particularly easy to pull off well with CSS, and grid obsessifs despise liquid layouts for other reasons. This, to me, is a reasonable compromise.

Cheers!

# gareth responded on 7th February 2006 with...

Stuart: Never one to not find a layout challenge interesting I had a stab at trying something similar using just CSS. I have a quick sample at www.morethanseven.net/temp/collapse.php.

Resize the window some and quaternary should move between being right of tertiary or below it.

It makes use of min-width so it’s non IE (to stop it all collapsing in on itself) but a little work might be able to sort that. Do with as you will, I’ll try and document a little and make a post of it.

# luxuryluke responded on 7th February 2006 with...

Wow!

# Simon Collison responded on 7th February 2006 with...

Gareth: Nice work - if only it weren’t for IE eh? I used JavaScript for exactly that reason. Min and max widths would have solved all my problems. Whilst mega-workarounds could have fixed things for IE in a roundabout way, I decided JavaScript was perfectly acceptable.

There. JavaScript is perfectly acceptable.

I feel better now..

# Gareth responded on 7th February 2006 with...

Simon: Completely agree on the javascript front, as I mentioned I’m doing something similar at the moment. Oh for min-width, etc. in IE7

# Simon Collison responded on 7th February 2006 with...

Oh for IE indeed. Incidentally, Stuart has posted his method: Drop Column Layout. Again, beautifully executed, just a shame about IE.

# Faruk Ates responded on 7th February 2006 with...

Damn Colly, this is marvellous stuff. Absolutely great, terrific job! :-)

# Nathan Holman responded on 8th February 2006 with...

great article. thanks.

# h2d2 responded on 8th February 2006 with...

I am using IE6/XPSP2 and although it does recognize that I’m at 1024px, it simply merges the two colums anyway. And I can still see the “hooray for…” bubble!

Any idea why it’s doing that?

# jboy responded on 8th February 2006 with...

if they have js disabled what happens next.
But still a goog item.

Job well done.

# Simon Collison responded on 8th February 2006 with...

jboy: I mentioned that. There is a default class in place whether JS is enabled or not, so just make sure whatever you want as the default is set in that class. The only thing is that it won’t get swapped on resizing, but I don’t have a problem with that, as the benefits of this solution outweight the others in my case. None of the other methods give me the pixel perfection I need - yet.

h2d2: Odd. That suggests that suddenly there is not enough room for both columns - maybe I’ve tweaked something as I’m redesigning - I’ll check it on the office PC. Thanks for the tip-off.

# h2d2 responded on 8th February 2006 with...

Colly: Your homepage renders as intended. But this entry doesn’t (and so doesn’t this one). So it’s most likely your entry content, like the photos on the music one and the code on this one.

# theBag responded on 8th February 2006 with...

Would this effect work on a fixed width layout that was centered? not left justified like it is here.

great work… Looks a treat!

# Giles responded on 8th February 2006 with...

The best bit about this technique (and the worst part about completely liquid layouts) is that you get to specify the text line length, to optimise readability and therefore usability.

Your running at about 65 char/line, in the main column, which is a pretty good length, for adults ;)

# John Labriola responded on 8th February 2006 with...

Great stuff Colly! I like how you bring existing content to the forefront. Something tells me you’ll start seeing a lot more of this.

My prediction for 2006, this will be common by the end of the year…

# Tae responded on 9th February 2006 with...

this is great and sharing it is even greater. thank you.

one question.. is there a way to easily adapt this to make a 4th column at the far right that does not wrap like the 3rd? i’m thinking about commercial sites with ads in the far right column that cannot be moved down.

# Arthur Bahadourian responded on 9th February 2006 with...

Great tutorial!

Q: How do you handle “View without Sidebar” link?

Thanks in advance,
Arthur

# Simon Collison responded on 9th February 2006 with...

h2d2: Think it’s all fixed now. Some padding I’d added had forced the comments textarea to shunt out a tad too far. Thanks for the feedback.

theBag: Yes, it does work with a centred layout. I had that working at one point. It’s just a case of adjusting the CSS carefully. If I get time I’ll write it up.

Tae: Ooh, nice idea. I’ll hopefully get time to try that too. Anyone else up for having a go?

Arthur: Good question! I’ve just put a quick fix in for now. basically it removes the middle column, and shows the right column if there’s enough room. I now need to adjust the script to hide that column if the window is too small. I’ll do it next time it rains.

# pixeldiva responded on 9th February 2006 with...

Really nice work. I saw something like this a while back but could never remember what site it was to go look more closely at how it was done, so wound up taking a different route with my own site.

One thing though - I think there’s something up with the script whereby it’s not firing the change to 3 columns until well over 990px. I’m one of those weirdos who has the start menu down the right hand side of the page rather than along the bottom and on my 1024x768 default display on my laptop this gives me a screen width of 973px as according to Chris Pedericks toolbar. When I resize the bar to half width that gives me 998px which should mean I get to see all 3 columns - only I don’t. It’s only if I hide it completely that I get to see all 3.

Not a huge deal, certainly, but just thought I’d point it out.

# eric responded on 9th February 2006 with...

Glad we’re on the same page from way up there ;) this isn’t about the width, but it’s about your redesign: what about using the famfamfam flags for your comments?

# Ismael responded on 9th February 2006 with...

I use something similar at my site. Cool.

# Cameron Adams responded on 10th February 2006 with...

I prefer switching stylesheets instead of a body class, because the effect is instantaneous. In your script here you use a window.onload handler, which allows the page to render before firing, and hence you can get flickering of content as it is resized, much as on the UXmag site, and on the Rosenfeld Media site before I corrected it.

With stylesheets, you can check the width and change the layout before any of the content has been downloaded and rendered—no flicker, no irritation.

# gareth responded on 10th February 2006 with...

Tae, Simon: Loitering in London after Carson and had time to play. Just updated my test page at morethanseven.net/temp/collapse.php with an additional ‘ads’ column fixed to the right. I quite like that approach.

# Simon Collison responded on 10th February 2006 with...

Pixeldiva: I too am using the WebDev toolbar to show window width, and the column is dropping/appearing at exactly 990px for me. Hmm…

Eric: I’ve downloaded the flags, but they’ll all need renaming before I can use them. I’ll do it soon. Cheers for the tip.

Ismael: Your version rocks!

Cameron: I simply did not want to use cookies here. I also stated in the article that I wanted the flicker of the column as a teaser (on this site anyway). Using the narrower wrapper as default would remove the flicker, so that option is available. It’s a personal choice, but not something I would consider “irritating”.

Gareth: Really, really good, none-Js version you’ve got there. Love it.

# Steve Dalgleish responded on 13th February 2006 with...

Simon, this is some top notch stuff.  Thanks so much for putting it in a little tutorial, I’ll definitely be using this.

# aoao responded on 14th February 2006 with...

love this JS and User in my Web

# Abba Bryant responded on 18th February 2006 with...

Take a look at John Resig’s reworking of your javascript using his JQuery library. Tres Bien!

# Prosto responded on 23rd February 2006 with...

By all hi! Good day! =)

# Tae responded on 23rd February 2006 with...

gareth: brilliant! i’ll be sure to steal it soon.. thanks!

# Martin responded on 2nd March 2006 with...

Hi. You have very nice website! Beautiful design and very interesting content.

Responses are now disabled Your ability to respond is disabled automatically some 30 days after articles are published, or manually much sooner if spamming guttersnipes target a particular article.

Prev 565 Next

Superfluous Aside

Archived in HTML & CSS, Design & Web

There are 48 responses

External References

Copyright © Mr. Simon Collison 2003-2017. Protected and licensed under a Creative Commons License. Grab the RSS feed

Engineered in Nottingham, scaffolded by ExpressionEngine, steam-pumped by United & kept alive with tea and hugs.