Skip to content

24 ways to impress your friends

Intricate Fluid Layouts in Three Easy Steps


Comments are ordered by helpfulness, as indicated by you. Help us pick out the gems and discourage asshattery by voting on notable comments.

Got something to add? You can leave a comment below.

Brian Rountree

Of course. Yahoo is actually very good at “eating it’s own dog food” . . . Specifically, as a Front End Engineer in the Media Group, I have worked with teams who have implemented the YUI Grids as well as the other libraries such as the connection manager, event, dom, animation and container libraries on Yahoo! Tech, Yahoo! Talent Show, Yahoo! News, the recently launched Yahoo! Food, and redesigned Yahoo! Health. Working with the folks on the platform team such as Nate has been an honor and pleasure. I am in awe of those guys almost every day!

Nate Koechley

@Christian: The entire YUI Library including Grids is available with a BSD license, perhaps the most open open-source license. Change or use the code in just about any way you like.

Though not an obligation in any way, let me invite you to share your experience and/or derivative work on our mailing list.

Christian Ready

I wonder, do the terms and conditions permit developers to change the id’s of certain elements in the CSS? The reason I ask is that it would really help add more semantic meaning to the document’s markup if you could use values of, “wrapper” instead of “doc3” and “subnav” instead of “yui-g.”

Jeff Croft

Great tutorial, Nate. I’ve been really impressed with the Yahoo grid setup (and the Javascript libraries, too) when I’ve played with it. It’s really nice to see it all laid out in a simple tutorial like this. Here’s hoping for widespread adoption!


@Christian: I know it’s the purist in us all but I’m not convinced it’s so important to change the doc3 ID – sure they could have been named after their widths or something but it doesn’t worry me personally. The added benefit of leaving as-is is when (if) Nate releases another version and you forgot to rename the IDs… By its very nature you can’t rename the classes that build the grid for you due to the dependencies.

About all I’ve done is add semantic IDs to some divs to act as a hook for the cascade and demonstrate to me the ‘important’ divisions on the page.

Thanks for the write-up Nate, this is actually clearer for me than the official page. I’ve only just released the redesign of my website and tonight I have already ported it to the YUI grids way on my dev server so I guess they’ll be another relaunch this weekend. The speed of putting layouts together is impressive.

Seb Frost

OK, so I’ve had a quick play, and it does indeed seem to work pretty well. Nice and quick to put a layout together, nice and stable across all browsers I’ve looked at (and I don’t care much about the ones I haven’t, so long as it’s readable which I assume it is).

But it grates with me.

I mean come on, in the example given we have 5 levels of nested divs, and 14 divs to create 8 areas of content.

The classnames are also horrible and not exactly easily remembered for someone starting out with this. They’re also a little counter-intuitive – when I looked at the source before reading the article I assumed “doc3” was designating a 3-column layout for example.

Maybe I’m just worried that this is going to simplify one aspect of my job so much that anyone will be able to knock out a semantic, table-free layout with no experience? ;)

I think one of the biggest problems in my mind is that this example (whilst complex in layout) is actually very simple – there’s no backgrounds, padding, different margins, overlapping elements etc etc that a client will ask for. It works nicely for a basic example with no styling, but I feel it’d actually be a nightmare to work with once you start trying to put a design into it?

And the use of css “hacks” worries me as well, I see both the underscore and the * hack used in this file – have we not learnt anything since IE7 came out? Do yahoo not think conditional comments are the way to go? If they have an article on this issue somewhere I’d be interested to see it.

But the biggest problem has to be those nested divs. They make me shudder they do. I could make the same layout in considerably less code using a table, and it’d have guaranteed browser support, and would be very easily maintainable by someone who wanted to (for example) change the width of a column. What have we gained by going from a simple table to a complex div-soup?


A developer’s approach to design: Create a tight little package that solves many layout requests by flipping a switch here and there. On the one hand, it’s brilliant. It’s a swiss army knife, easily deployable, very useful. You want it? We got it – just dial the right combination.

On the other hand, I don’t know any html designer who wouldn’t take pride in creating his/her own html and css.

This is great for an IT group at a corporation to share with various departments that need their own special layouts. I see it being good for some one-man hosting company who offers ‘customized web design’ and can deploy these pretty quick. I don’t see it being so useful for independent designers, as they will want to do their own html and css. It’s not for non-designers like some guy throwing out an ‘about me’ page for his handyman businss, as who would want to learn “yui-u” and “yui-gb” and “doc3”?

Overall, it’s a powerfully little package.


@Seb and anyone else concerned about the * and _ hacks might want to look at my CSS framework. It replaces old hacks with several HTTP requests although you can reduce that number by combining style sheets on the production server. It really just boils down to what works (or is acceptable) for any given project, hence the term framework I suppose.

It may be div-soup and involve more code than a table, but it linearises better than a nested tables-based design which dictates structure and position over a div layout that is structure put into position by CSS.

Nate Koechley

Thanks for the comments everybody. I’ve addressed them below:

I’ve heard the “divitis” charge before, but disagree strongly. The W3C says divs are “for adding structure to documents.” I take their guidance to heart: “this content is part of a column group” is correct usage. I’ve articulated that position on my blog and welcome discussion:

+ Regarding class and ID names:

Names should not be based on appearance, but on meaning. For maximum extensibility, choose names that express semantic meaning (derived from the element’s content), and/or structural meaning (derived from the element’s role in the DOM’s tree). Good structural names include “footer” and “module”; good semantic names include “price” and “date”.

The common “doc” in doc, doc2, and doc3 is meaningful because this particular div is the document’s root node. It has no bond to a particular rendition or device. Similarily, “-b” (block), “-g” (grid), and “-u” (unit) classnames are meaningful yet neutral. The alternative, what-it-looks-like names such as “left” and “doc950px”, is contextually brittle (i.e., mobile) and temporally brittle (because things change). These are the same reasons professional consensus says class=“redButton” and class=“smallBoldVerdana” are undesirable.

+ Regarding the hacks for IE (*property) and IE7 (_property):

You’re right, you could pull those out into version-specific sheets exposed by conditional comments. I’ve included them in a single file in this case for two reasons. First, additional HTTP requests hurt performance. I value performance before validity, especially for infrastructure.

Second, the main argument against including CSS hacks — that they’re hard to manage — is moot in this case. CSS hacks are tedious, risky, and expensive to manage, and for those reasons I discourage intermingeling them in large codebases. But in this case the file is of encapsulated scope, is centralized, and has dedicated and permanent maintenance staff.

+ Does it work for demanding designs?

While everything’s breakable, the short answer is yes. It’s been used successfully on glossy sites with all the Web 2.0 trimmings: drop shadows, nested borders, rounded-corners, gradients… YUI Grids is a dependable skeleton. If you need more hooks, it’s rugged enough that you can embed your own markup and it won’t break.

Great to hear you were able to port your redesign so quickly! Very happy to hear it.

I definitely hear you when you say “you don’t know any HTML designer who wouldn’t take pride in creating” their own, It’s true, us geeks are a proud lot. But for my money, I don’t know many without something more interesting to do than reinvent the wheel. Efficient tools let us reach farther, but are never required.

+ What about those not interested in handcoding?

Dav Glass has created an outstanding wizard for building YUI Grids:

Of course, your general argument applies to any tool, in any context, from “Ruby on Rails makes programming too easy!” to “painting with premixed colors is boring.”

@Michael: Thanks!

Andrew Ingram

This may have been addressed already, but it’s late and i’m too tired to read through everything that’s been said in detail.

My issue with YUI Grids is that regardless of whether the class names used to hook the styles are meaningful, you’re doing your markup based on your styles rather than the other way round.

It may not be that much tag soup (though definitely more structural markup than necessary), but it seems to me that it’s a step backwards in terms of seperating style from content. It’s hard work producing markup that has no fluff, but I like to think that it’s worth it, even with all styles disabled every single character in the document source is adding to the meaningful information content of the page (I accept that it’s not always possible but it’s something we should aim for).

Don’t confuse this for blind designer or coder pride concerning my beautiful hand-crafted markup and style rules, i’m all in favour of using frameworks – I use YUI Fonts quite regularly and am quite interested in learning Django, Rails et al. But unless i’m missing some big part of YUI Grids, i can’t see how it’s the right idea.

Nate Cavanaugh

I think your heart is in the right place, but the idea for the grids is all wrong. Like Andrew said, this is a step backwards.
In order to change the look of the site, I now have to touch the structural layer. So now presentation is being relegated back to the markup, which is just all kinds of bad.

Maybe I am missing something, though.

Greg Raven

Is it just me, or does the second column in the second row of the complex example not align vertically with the third column in the first row? Actually, it seems that the third column in the first row is the one out of alignment, compared to the second columns in rows two and three.

I don’t think I’d ever use a layout exactly like this, but this is the kind of thing that would surface eventually in one of my layouts, given my luck with CSS layouts.


Hi, Nate!

I know, I’m late, but hey, better late than never!

How do you solve following case?
row 0,3 and 4 are 100% width.
col2 is 240px right
col1 takes the rest.

row0 header
row1 col1 | col2
row3 col3
row4 footer

And now the tricky part!
Due to seo optimizing, I need to display things in the following html source order: 1. row0, 2. col3, 3. col2, 4. col1, 5. row4

How will you accomplish that, with yui???
All I got is following, with some trickery:
Click this Picture
And I’ve things in following html source order:

You see I need things in 3,2,1 order and 3 is the next row.
I hope anyone reading this can help.

Kind regards

Peter Bowey

One of the recent innovations to this layout problem has been a true fluid layout grid. See a live visual at and the source to use this at

I managed replace the fixed 960 grid system with the fluid layout of the above source. You will need to make few small changes, however, it is easy enough and does offer a true fluid layout for this Inspirion template. The other good change is “source order” = placing important content earlier in the final code -> SEO!

Note: this fluid method also add an extra option of SEO preferred source ordering (via push / pull classes in the 960.css file (see below). This means you can shift the main content of your site before the left (or right) menus.

/* —————————————————————————————————————— */

/* 960 Fluid Grid System ~ Core CSS. Learn more ~ Licensed under GPL and MIT. */

/* =Containers

{ width:92%; margin-left:4%; margin-right:4%;

/* =Grid >> Global
{ display:inline; float:left; margin-left:1%; margin-right:1%;
.container_12 .grid_3,
.container_16 .grid_4 { width:23% ;}
.container_12 .grid_6,
.container_16 .grid_8 { width:48% ;}
.container_12 .grid_9,
.container_16 .grid_12 { width:73% ;}
.container_12 .grid_12,
.container_16 .grid_16 { width:98% ;}

/* =Push Pull Grid >> Global
.pull-1, .pull-2, .pull-3, .pull-4,
.pull-5, .pull-6, .pull-7, .pull-8,
.pull-9, .pull-10, .pull-11, .pull-12,
.pull-13, .pull-14, .pull-15, .pull-16,
.push-1, .push-2, .push-3, .push-4,
.push-5, .push-6, .push-7, .push-8,
.push-9, .push-10, .push-11, .push-12,
.push-13, .push-14, .push-15, .push-16 { float:left;position:relative;

/* =Grid >> Children (Alpha ~ First, Omega ~ Last)
.alpha { margin-left:0 ;}
.omega { margin-right:0 ;}
.alpha5 { margin-left:0.666% ;}
.omega5 { margin-right:0.666% ;}
.alpha7 { margin-left:0.75% ;}
.omega7 { margin-right:0.75% ;}

/* =Grid >> 12 Columns
.container_12 .grid_1 { width:6.333% ;}
.container_12 .grid_2 { width:14.666% ;}
.container_12 .grid_4 { width:31.333% ;}
.container_12 .grid_5 { width:39.666% ;}
.container_12 .grid_7 { width:56.333% ;}
.container_12 .grid_8 { width:64.666% ;}
.container_12 .grid_10 { width:81.333% ;}
.container_12 .grid_11 { width:89.666% ;}

/* =Grid >> 16 Columns
.container_16 .grid_1 { width:4.25% ;}
.container_16 .grid_2 { width:10.5% ;}
.container_16 .grid_3 { width:16.75% ;}
.container_16 .grid_5 { width:29.25% ;}
.container_16 .grid_6 { width:35.5% ;}
.container_16 .grid_7 { width:41.75% ;}
.container_16 .grid_9 { width:54.25% ;}
.container_16 .grid_10 { width:60.5% ;}
.container_16 .grid_11 { width:66.75% ;}
.container_16 .grid_13 { width:79.25% ;}
.container_16 .grid_14 { width:85.5% ;}
.container_16 .grid_15 { width:91.75% ;}

/* =Prefix Extra Space >> Global
.container_12 .prefix_3,
.container_16 .prefix_4 { padding-left:25% ;}
.container_12 .prefix_6,
.container_16 .prefix_8 { padding-left:50% ;}
.container_12 .prefix_9,
.container_16 .prefix_12 { padding-left:75% ;}

/* =Prefix Extra Space >> 12 Columns
.container_12 .prefix_1 { padding-left:8.333% ;}
.container_12 .prefix_2 { padding-left:16.666% ;}
.container_12 .prefix_4 { padding-left:33.333% ;}
.container_12 .prefix_5 { padding-left:41.666% ;}
.container_12 .prefix_7 { padding-left:58.333% ;}
.container_12 .prefix_8 { padding-left:66.666% ;}
.container_12 .prefix_10 { padding-left:83.333% ;}
.container_12 .prefix_11 { padding-left:91.666% ;}

/* =Pull Pull Class >> 12 Columns
.container_12 .pull-1 { left:-8.333% ;}
.container_12 .pull-2 { left:-16.666% ;}
.container_12 .pull-3 { left:-25% ;}
.container_12 .pull-4 { left:-33.333% ;}
.container_12 .pull-5 { left:-41.666% ;}
.container_12 .pull-6 { left:-50% ;}
.container_12 .pull-7 { left:-58.333% ;}
.container_12 .pull-8 { left:-66.666% ;}
.container_12 .pull-9 { left:-75% ;}
.container_12 .pull-10 { left:-83.333% ;}
.container_12 .pull-11 { left:-91.666% ;}
.container_12 .pull-12 { left:-100% ;}

.container_12 .push-1 { left:8.333% ;}
.container_12 .push-2 { left:16.666% ;}
.container_12 .push-3 { left:25% ;}
.container_12 .push-4 { left:33.333% ;}
.container_12 .push-5 { left:41.666% ;}
.container_12 .push-6 { left:50% ;}
.container_12 .push-7 { left:58.333% ;}
.container_12 .push-8 { left:66.666% ;}
.container_12 .push-9 { left:75% ;}
.container_12 .push-10 { left:83.333% ;}
.container_12 .push-11 { left:91.666% ;}
.container_12 .push-12 { left:100% ;}

/* =Prefix Extra Space >> 16 Columns
.container_16 .prefix_1 { padding-left:6.25% ;}
.container_16 .prefix_2 { padding-left:12.5% ;}
.container_16 .prefix_3 { padding-left:18.75% ;}
.container_16 .prefix_5 { padding-left:31.25% ;}
.container_16 .prefix_6 { padding-left:37.5% ;}
.container_16 .prefix_7 { padding-left:43.75% ;}
.container_16 .prefix_9 { padding-left:56.25% ;}
.container_16 .prefix_10 { padding-left:62.5% ;}
.container_16 .prefix_11 { padding-left:68.75% ;}
.container_16 .prefix_13 { padding-left:81.25% ;}
.container_16 .prefix_14 { padding-left:87.5% ;}
.container_16 .prefix_15 { padding-left:93.75% ;}

/* =Pull Pull Class >> 16 Columns
.container_16 .pull-1 { left:-6.25% ;}
.container_16 .pull-2 { left:-12.5% ;}
.container_16 .pull-3 { left:-18.75% ;}
.container_16 .pull-4 { left:-25% ;}
.container_16 .pull-5 { left:-31.25% ;}
.container_16 .pull-6 { left:-37.5% ;}
.container_16 .pull-7 { left:-43.75% ;}
.container_16 .pull-8 { left:-50% ;}
.container_16 .pull-9 { left:-56.25% ;}
.container_16 .pull-10 { left:-62.5% ;}
.container_16 .pull-11 { left:-68.75% ;}
.container_16 .pull-12 { left:-75% ;}
.container_16 .pull-13 { left:-81.25% ;}
.container_16 .pull-14 { left:-87.5% ;}
.container_16 .pull-15 { left:-93.75% ;}
.container_16 .pull-16 { left:-100% ;}

.container_16 .push-1 { left:6.25% ;}
.container_16 .push-2 { left:12.5% ;}
.container_16 .push-3 { left:18.75% ;}
.container_16 .push-4 { left:25% ;}
.container_16 .push-5 { left:31.25% ;}
.container_16 .push-6 { left:37.5% ;}
.container_16 .push-7 { left:43.75% ;}
.container_16 .push-8 { left:50% ;}
.container_16 .push-9 { left:56.25% ;}
.container_16 .push-10 { left:62.5% ;}
.container_16 .push-11 { left:68.75% ;}
.container_16 .push-12 { left:75% ;}
.container_16 .push-13 { left:81.25% ;}
.container_16 .push-14 { left:87.5% ;}
.container_16 .push-15 { left:93.75% ;}
.container_16 .push-16 { left:100% ;}

/* =Suffix Extra Space >> Global
.container_12 .suffix_3,
.container_16 .suffix_4 { padding-right:25% ;}
.container_12 .suffix_6,
.container_16 .suffix_8 { padding-right:50% ;}
.container_12 .suffix_9,
.container_16 .suffix_12 { padding-right:75% ;}

/* =Suffix Extra Space >> 12 Columns
.container_12 .suffix_1 { padding-right:8.333% ;}
.container_12 .suffix_2 { padding-right:16.666% ;}
.container_12 .suffix_4 { padding-right:33.333% ;}
.container_12 .suffix_5 { padding-right:41.666% ;}
.container_12 .suffix_7 { padding-right:58.333% ;}
.container_12 .suffix_8 { padding-right:66.666% ;}
.container_12 .suffix_10 { padding-right:83.333% ;}
.container_12 .suffix_11 { padding-right:91.666% ;}

/* =Suffix Extra Space >> 16 Columns
.container_16 .suffix_1 { padding-right:6.25% ;}
.container_16 .suffix_2 { padding-right:16.5% ;}
.container_16 .suffix_3 { padding-right:18.75% ;}
.container_16 .suffix_5 { padding-right:31.25% ;}
.container_16 .suffix_6 { padding-right:37.5% ;}
.container_16 .suffix_7 { padding-right:43.75% ;}
.container_16 .suffix_9 { padding-right:56.25% ;}
.container_16 .suffix_10 { padding-right:62.5% ;}
.container_16 .suffix_11 { padding-right:68.75% ;}
.container_16 .suffix_13 { padding-right:81.25% ;}
.container_16 .suffix_14 { padding-right:87.5% ;}
.container_16 .suffix_15 { padding-right:93.75% ;}

/* =Clear Floated Elements
html body * span.clear,
html body * div.clear,
html body * li.clear,
html body * dd.clear
{ background: none; border: 0; clear: both; display: block; float: none; font-size: 0; list-style: none; margin: 0; padding: 0; overflow: hidden; visibility: hidden; width: 0; height: 0;

/* */
{ clear:both; content:’.’; display:block; visibility:hidden; height:0
{ display:inline-block
} * html .clearfix
{ height:1%
{ display:block
/* Adds a multiplier of 3 to the grid */
.container_16 .grid_5plus5
{ width:31.25%;
/* END FLUID 960 CSS */
Now we can place the main content section before the left menu:

The CSS .push-x .pull-x class allow for custom a layout ordering that’s independent from source ordering!

Peter Bowey


Hi Nate,

Thanks for YUI!

Idealistic imperfections aside, it works perfectly for what I’ve been doing in the real world, and I’m neither a fulltime designer nor engineer.

The sites I have built with YUI are generally using one of the templates, and typically I’ll split the default header (hd) into multiple columns with nesting for placement of a logo, banner, and a sign in box.

That noted, I’m little confused how to add multiple headers and footers. I have, for example, tried to just add a hd1 and hd2 after hd to have 3 header areas on top of each other. This has mostly worked and is the easiest way for me to style them.

My first question is; if I want extra headers, should I be adding them as I described, or as nested headers within the default hd using some kind of block/grid naming scheme I have missed in the documentation?

If not, is there any naming scheme I should be using for extra headers and footers so as to avoid rendering errors? hd, hd1, hd2, etc are what I have played with.



Well, most of the negative commentary seems to come from people who have yet to use the YUI stuff in actual production. The only problem I really ran into using the yui grids came down to inheritance and nesting, and thats really more a feature/problem of css then it is with the grids solution itself. (just try nesting gb or gc classes under g ones or vice versa, you’ll see).

But those problems aside, which are not really problems, since it forces you to rethink how you were planning your layout anyways, the grids are great. I’ve already used them on 3 different projects successfully and have to say I’m not going to be wasting my time going forward by trying to reinvent the wheel.

As to the hacks comments: conditional comments, separate css files, those are all great ideas, but those are perfect world solutions, not real world. If you find yourself having to hack ALOT, then someting is WRONG with your layout/markup, and you are creating those problems for yourself, not the browsers. In any large project I’ve worked on, by the time i’m done I have maybe 3 or 4 IE specific _ hacks in my markup (almost always related to the whole has layout problem), and if the site is live and working fine, I’m TOTALLY ok with that, because that means I’m getting paid. ;)

Impress us

Be friendly / use Textile