hello, I encountered a problem that is seemingly easy to solve but I just can't find a correct way to do it. I have a container (let's call it box 1) in which there is a box with a specific background (box 2) and I want to float a third element beside the second one (box 3). But: a) The third element is optional b) If box 3 is present, I want box 2 to be placed _beside_ and not overlap (or appear under) box 3 c) If box 3 is absent, I want box 2 to take all the width of box 1... I happened to find a way to do this under IE 6/7 but FF and Opera render it in a different way... To illustrate: http://www.wave460.net/misc/float_problem/ (sorry it's coded with inline css - i did it in a bit of a hurry) Examples 1-5, 2-6, 3-7, 4-8 are analogous - iow, the properties used are the same (not counting the missing side-box)... What I would like to get is a consistent style that would give me an effect equivalent to examples 2/4 with the box present - and 5/7 with the box absent... and - of course - IE renders example 1 almost the same as example 2 so that is almost the correct solution - BUT - it doesn't work under FF and Opera... I know it probably could be done with some kind of javascript but that would be the last resort since I would rather not use scripting for plainly presentional purpose... Thanks in advance for any help...
This is simply a matter of establishing block formatting contexts, what we know in IE as hasLayout. IE mis-implements it, but it's close enough for guv'ment work. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head> <meta name="generator" content= "HTML Tidy for Linux/x86 (vers 1 September 2005), see www.w3.org" /> <title></title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta name="editor" content="Emacs 21" /> <meta name="author" content="Gary Turner" /> <style type="text/css"> /*<![CDATA[*/ html, body { margin: 0; padding: 0; } body { font: 100% arial, helvetica, sans-serif; color: black; background-color: white; } p { font-size: 1em; margin: 1.25em 0 0; } div { padding: 5px; border: 3px solid black; } h1, h2, h3 { font-family: georgia, serif; } .container { overflow: hidden; background-color: red; width: 600px; /*sets hasLayout in IE6*/ margin: 25px auto; } #flot1, #flot2 { background-color: yellow; float: right; } #flot1 { width: 100px; } #flot2 { width: 150px; } .therest { overflow: hidden; /*creates block formatting context equivalent to IE7 hasLayout*/ background-color: orange; display: inline-block; /*hasLayout tripswitch for IE6*/ } .therest { display: block; /*resets display without resetting hasLayout*/ } /*]]>*/ </style> </head> <body> <div class="container"> <div id="flot1"> <p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis porta quam vel dolor. Nam eu. </p> </div> <div class="therest"> <p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis porta quam vel dolor. Nam eu. </p> </div> </div> <div class="container"> <div id="flot2"> <p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis porta quam vel dolor. Nam eu. </p> </div> <div class="therest"> <p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis porta quam vel dolor. Nam eu. </p> <p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed consectetuer arcu ac diam. Nulla ut sem sit amet leo mollis tincidunt. Duis rutrum turpis sit. </p> <p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed consectetuer arcu ac diam. Nulla ut sem sit amet leo mollis tincidunt. Duis rutrum turpis sit. </p> </div> </div> <div class="container"> <div class="therest"> <p> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis porta quam vel dolor. Nam eu. </p> </div> </div> </body> </html> Code (markup): cheers, gary
first things first, thank you very much again but... if it's possible, I'd like to clear the things up a bit. Up until now, I thought that hasLayout was kind of an IE only matter - obviously it's not... the one thing that strikes me most is how "overflow: hidden" works in this example - 1) it has an effect of clearing the inside of the container block but such behaviour is not very obvious to me... what is the exact effect of setting overflow:hidden in this case? 2) the other effect - creating a margin to the right of the box is also not that apparent, but much more explainable... thanks again, blue...
To tell the truth, I had not made the connection until recently. IE implements hasLayout in a willy-nilly manner. Any of these will trigger it: display: inline-block height: any value float: left or right position: absolute width: any value writing-mode: tb-rl zoom: any value overflow: [other than visible] IE added the overflow as a last minute thing in IE7. Properties that should trigger a new block formatting context (the "official" name) affecting height: auto, are display: table display: table-cell float: [other than none] overflow: [other than visible] and I don't know about inline-block, because no one really implements it. The reason hasLayout is so hated is that IE triggers it in so many ways that it almost can't be avoided. The hasLayout behavior is mostly undesirable. The simplest way to understand it is to consider the behavior of a table. It should be obvious that a table must enclose its children (absolute positioning excepted), even float elements when height is auto. When height is set to auto, the default, how can hidden overflow be determined, the same with auto producing scrollbars? So the height is computed to extend to the bottom of the child nodes (elements or PCDATA (text)). Were the height set, the overflow property would act as expected. A margin isn't created. The box is actually sitting beside the float. If you set a percentage width, you'll see the reference width is the remaining space, rather than the full width including the float width(s). This is where IE is considered to have a faulty float model. Merely setting any height triggers hasLayout where it acts that way. Too, if you set a margin, it will space your element from the float edge instead of the parent's edge. All that said, I may be all wrong. I know the practical effect, but the nitty-gritty under the hood mechanisms may be completely different from my description. cheers, gary
Pardon the interruption, but I've been reading through some threads, trying to glean some additional coding wisdom, and this just struck me. I was under the impression that if you have something float to the left (Say, an image), and then you have an object come up to fill the space to the right of it (say, a paragraph), both inside a parent container (say a div), and that if you institute a block layout (such as with "overflow:hidden" on the paragraph) that if you place the margin-left element on the paragraph, it should calculate the margin based on the location of the right edge of the image. Is that not the case?
It is in IE's hasLayout, because there are too many of the wrong things that trigger it, and too many things that are affected by its presence or absence. When a new block formatting context is properly and purposefully created, there is great power to be found. Consider, though, the demo here. Remove the {overflow: hidden;}, and put a width: 90% on .therest, you get very different layouts. IE has triggered hasLayout contrary to specs. There are other bugs. If an element is positioned, it serves as a positional reference for AP descendants (see your other thread). That's not good enough for IE; it must also have layout, also contrary to the specs. cheers, gary
*wince* Thanks. A lot of people complain about the difference, and I think that a big part of why IE ignores the international standards, is that since they're a monopoly, they're trying to make it hard to do anything without keeping IE. If not for windows update (which they likely coded to only work in IE only so that people would have to use IE), and web development, I wouldn't have it on my computer at all. They probably figure that if they force people to code for their pages, it'll look badly in FireFox and other browsers, and people will keep using IE. And people that tout Firefox and other browsers, but have code that apparently is badly done (due to IE rendering it poorly) will seem less credible to the crowd that uses IE.