- From: Anton Prowse <prowse@moonhenge.net>
- Date: Sun, 15 Aug 2010 09:29:52 +0200
- To: "www-style@w3.org" <www-style@w3.org>
It ends in a cliffhanger... Why is clearing floats desirable? ================================= There are various reasons. The available space next to a float may be rather too narrow for certain content to look pleasing when flowed alongside. Section headings often look better below the floats of previous sections rather than alongside them. So we need a mechanism for pushing the clearing element downwards? ================================================================== Exactly. Can we use increased top margin on the clearing element? ======================================================== No, that would mean that if the top margin of the clearing element collapses with the float's parent, then the float would move down too! <div> <div style="float:left; width:100px; height:100px></div> <div style="clear:left; margin-top:50px">text</div> </div> What about introducing spacing below the clearing element's top margin? ======================================================================= No, that would stop its first child's top margin from collapsing. <div> <div style="float:left; width:100px; height:100px></div> <div style="clear:left"> <h2 style="margin-top:50px">text</h2> </div> </div> So we have to prevent the clearing element from collapsing margins with its parent? ======================================================================= Yes. That's half of what clearance is; it's a margin collapsing interrupt. (The other half of it is about moving the clearing element to the desired position.) Shouldn't the clearing element still collapse margins with previous siblings? =================================================================== No, that would mean that when we moved the clearing element to the desired position, the previous siblings would move too! So the clearing element can't collapse with any previous margin? ================================================================ Exactly. We interrupt margin collapsing immediately before the clearing element. Does interrupting margin collapsing have side-effects? ====================================================== Yes; in particular, the float can itself move upwards! <div>text</div> <div> <div style="float:left; width:100px; height:100px"></div> <div style="clear:left; margin-top:50px">text</div> </div> Heh, that's funny. So what's the desired position to which we move the clearing element? ======================================================================= So that its top border edge is the lower of: - below the float - where it was before margin collapsing was interrupted The second consideration addresses the case where the float moves upwards after interrupting margin collapsing. It would be strange to move the clearing element upwards! Prior to clearing, it was as low down as it was for good reason: sensible margin collapsing with surrounding in-flow elements. Why consider the top border edge and not the top margin lump edge? ================================================================== That's just the way it is. Bottom margin on the float can be used to provide separation. Simple! So what's the catch? ============================ The presence of "self-collapsing" elements whose own top and bottom margins collapse makes life difficult. Why aren't self-collapsing elements discarded from the layout? ============================================================== Even though they're invisible, they interact with other document elements in the normal ways. For example, their width establishes the available space for floated children, and of course their vertical margins affect the position of descendants and subsequent elements. And discarding them would be the cause of strange discontinuities: imagine an inline element containing a block-level element containing a float; the layout would change significantly depending on whether the block-level element had non-zero vertical borders or padding. Why aren't self-collapsing elements prevented from collapsing their own margins? ======================================================================= Then they would frequently affect the layout, in very, very common situations (such as an empty P element in amongst non-empty P elements). With margin collapsing, they can often avoid having an impact. So we're stuck with them. Why are they problematic? ==================================================== For one thing, there's no natural place that can be identified as their border box. And the border box position is necessary to determine where to place any floated and absolutely positioned children. By convention, if a self-collapsing element collapses its margin with its parent's top margin, then its top border edge position is defined to be that of its parent; and if it doesn't, its top border edge position is defined to be where it would be (relative to the canvas) if it had a non-zero bottom border (noting that the temporary assumption of a non-zero border changes how margins collapse around the element). That convention sound kind of arbitrary! What gives? ===================================================== Well, in the first case, it's the only way of ensuring that the self-collapsing element's border area lies within the parent's border area. It would be strange if the element's floated children ended up higher than its parent's top border! In the second case, it /is/ kind of arbitrary. The position has to be somewhere in the margin lump in which it participates. It would be strange if it were higher than where it would be if the element actually had a non-zero border top. Likewise, it would be strange if it were lower than where it would be if the element actually had a non-zero border bottom. Based on the results of test cases, the lowest position within those two bounds was chosen (although only after many years of the spec choosing the /highest/ position!). And how does all this relate to clearance? ========================================== If a self-collapsing element has 'clear' set, we have to determine whether its top border edge is below the bottom outer edge of all relevant floats. Easy, right? The convention gives us the top border edge position! =================================================================== Yes... but oddly it's not /that/ position that's used. It's a different position, this time defined as where it would be (relative to the canvas) if the clearing element really did have a non-zero *top* border. Why? ==== Because there's an error in the spec! Stay tuned for the follow-up, in which we demonstrate precisely why this part of the spec is just silly... Cheers, Anton Prowse http://dev.moonhenge.net
Received on Sunday, 15 August 2010 07:31:50 UTC