Wrapping a Div around Floats in HTML
The second of my digressions onto HTML looks at how to make sure that a DIV is at least as high as the floating DIVs it contains.
If you do something like:
<div id='outer'> <div style='float:left'>Content One</div> <div style='float:left'>Content Two</div> <div style='float:left'>Content Three</div> </div>
and want div#outer to encompass the three content divs, you find a browser incompatibility. IE7 does that I want - the enclosing div encloses its children. Other browsers do what the CSS standard says is the right thing: div#outer is one pixel high and the rest of the divs descend below it.
I want it to work on all browsers, however. After various playing around I discovered that:
<div id='outer'> <div style='float:left'>Content One</div> <div style='float:left'>Content Two</div> <div style='float:left'>Content Three</div> <div style='clear: both; height: 0'></div> </div>
seems to work. [Interestingly, although I'm working exclusively in XHTML, using <div/> doesn't work - the XHTML spec recommends that you don't have empty tags like div (anything that normally contains content), but this isn't a normative part of the spec, so browsers should really support full XML syntax in this regard.]
The application of all this is that I can now apply a vertically tiled 1px high background image to div#outer, with column shading on it, and have the different height columns all appear to be full-height - something that is very difficult to do by making the floating divs actually the same height. It is a solution that avoids many of the accessibility and fragility problems of the "one true layout" approach.
Combining this with the previous blog post I can now get full-height columns in any order, which is what I needed.
Comments
IIRC it will work with empty when you serve it as application/xhtml+xml. Otherwise it will treat it as a tag soup... (the same goes for )
Posted by: jpc | July 9, 2007 11:14 AM
I usually have a class 9if not more) in my css pages just for such purposes.
.clearHak { clear: both; }
Also, div is not a self-closing tag. You have to have the /div in as well, so that's working as it should.
One more thing you should add in to be XHTML compliant is put something inside the <div> & </div> tags. I usually put a non-breaking space in there...
Posted by: Walker Hamilton | July 9, 2007 08:53 PM
@jpc - thanks, it didn't seem to work when I'm declaring mimetype via a meta tag, but i'll try it as a server header and see.
@Walker - the height is important - i normally have a clear class too, but use it on content - in this case I want not one pixel showing. Also according to the XHTML spec you don't need anything inside the tag, not even a closing tag. The XHTML1 spec simply says that older browsers might get confused with valid XHTML syntax, so you might want to put the explicit closing tag. If the browser was properly XHTML complient it wouldn't care - but the spec gives advice based on the idea that the browser wouldn't understand XHTML, so you make your XHTML as HTML-like as possible.
Posted by: Ian | July 10, 2007 12:46 AM
If you're not already aware of it, check out css-discuss.
It's a mailing list and wiki all about CSS.
In particular, you may be interested in this page:
http://css-discuss.incutio.com/?page=CssLayouts
Posted by: Jeremy Dunck | July 10, 2007 05:58 AM
You can accomplish the same by adding
div#outer { overflow: hidden; }
to your CSS, thereby avoiding a meaningless tag in your html. This will make all browsers resize the div to contain it's inner block elements.
Posted by: Gistybit | July 11, 2007 10:57 AM
[from memory maybe I'm wrong]
Can't you just float the container div as well and that will make it expand with floated elements inside it?
Posted by: Jökull | July 11, 2007 02:21 PM
@gistybit
Thankyou! I didn't find that searching about, but that does seem to work and is more semantically pure.
It worries me, however, that this is behaviour neither mandated, nor endorsed by the spec, whereas div clear is. It also seems like a completely unrelated side effect to what overflow is supposed to do. But hey, it might be one of those features that just gets propagated because it works.
Posted by: Ian | July 11, 2007 05:04 PM
@ian
No problem - it's what i use all the time! :-)
I read it a long time ago somewhere which also pointed to a page on w3.org where this behaviour was described, but i can't seem to find anything now.
"When overflow:hidden is set without a height property, the height is set to enclose the elements it contains", or something along those lines.
I'm glad that you write about it in your blog, because people run into the problem all the time, and don't understand why margins and height percentages aren't interpreted according to what dimensions they think that the parent element has.
Posted by: Gistybit | July 12, 2007 03:35 PM