Our grid system is very similar to Yahoo's - it's designed to nest two units inside of a container and then further nesting takes place in one of the two units. Our system can scale to infinite nesting in browsers that support first-child selectors, and for those that don't we bake a nasty mix of descendent selectors to achieve a baseline of 4 levels of nesting (which seems pretty sufficient for most projects).
A fixed layout of 180-px on the left and fluid on the right looks like this in HTML:
<div class="g-section g-tpl-180">
<div class="g-unit g-first">
<div class="box-1">1</div>
</div>
<div class="g-unit">
<div class="box-2">2</div>
</div>
</div>
This grid/horizontal column layout is done in CSS by making the g-first element float:left and then have a fixed width:180px then the second g-unit float:none and margin-left:180px. So, since something is floating here, we want our g-section to contain it.
For containing floats, here's what I've found:
* Clearfix is nice, but doesn't work when nesting sections within units, so for our framework it is useless.
* Faux Absolute Positioning is pretty cool, but doesn't mix well on pages that don't adopt this approach whole hog (i.e. everything has to be inside of a div with class="line". So that's out.
* overflow:hidden - Overflow hidden for a CSS framework is like using crack - it's solves the immediate problem nicely, but as things build up and edge cases kick in, it's unsustainable and gross. Hiding parts of the UI and not providing users with a scroll bar is just plain wrong, even if it makes your design "look" good still. All sorts of things in Web Apps will get you into this situation - dynamic-width/column data tables, form input elements, images, etc.. Cutting them off and asking your user to get a bigger screen is wretched.
I'm going to paste the code and comments I'm currently using for g-section below. Hopefully it will be of use to someone stumbling across this. I have unit tests that test against float-drops and sizing of the template is all the basic cases as well as cases where the sections are nested up to 4 in depth as well as nested inside of floats.
Update May 10: So it seems that the fix for a pure float-left container is to set width to be auto for the outer container and then display: inline for nested g-section's. If that makes sense then you'll be happy to hear it solves the problem of width aggregation for the inline-blocks!
I welcome your suggestions - thanks!
/**
* g-section fundamentally has to clear floats. There are many ways to do this.
* This technique is nice because it doesn't rely on overflow: hidden, which
* has the potential to hide your content in situations where a fixed size
* node takes up too much space (like a big table, or a text input or image.
* Works in Webkit, IE8, and FF3.
*/
.g-section {
width: 100%;
vertical-align: top;
display: inline-block;
}
/**
* IE7-only hack. Nicely IE7 will clear floats with just block display
* and hasLayout.
*/
*:first-child+html .g-section {
display: block;
}
/**
* IE6 cannot hang with overflow: visible. If we use the IE7 display block
* trick in IE6 we get severe float drop in nested grids.
*/
* html .g-section {
overflow: hidden;
}
/* FF2 can't actually hang with overflow: visible. */
@-moz-document url-prefix() {
.g-section {
overflow: hidden;
}
}
/**
* FF3 now needs to be reset after the previous block which affects it as well.
* We target the tt element in this hack because no one uses it.
*/
@-moz-document url-prefix() {
.g-section,tt:default {
overflow: visible;
}
}
/* Forces "hasLayout" fixing a gamut of bugs in <= IE7. */
.g-section,
.g-unit {
zoom: 1;
}
3 comments:
Agreed with Thierry. For instance, inline-block does not work to contain floats in widthless containers.
Yeah, no magic bullets for sure. All of these approaches seem to have their own sucky drawbacks.
@Thierry: I've never seen anyone defend hasLayout! That's curious, and I wonder if you might have more to say about it.
@Ernest: sure, that's why in my example I had to set the width to 100%, but for a grid container, that's an ok thing to do.
The g-section at the end doesn't need the zoom: 1 declaration since the element already has a layout because of the 'width: 100%' in the first rule.
Post a Comment