Closed Bug 45830 Opened 25 years ago Closed 25 years ago

[MARGIN-C]An empty DIV "clear: left" does not clear a "float: left" image

Categories

(Core :: Layout, defect, P3)

x86
All
defect

Tracking

()

RESOLVED INVALID
Future

People

(Reporter: chris, Assigned: attinasi)

Details

(Keywords: css3)

Attachments

(3 files)

I wish to have some text wrapping around a "float: left" image with both completely enclosed by a DIV. As per the CSS2 spec at http://www.w3.org/TR/REC- CSS2/visuren.html#img-float2p (sec 9.5) floating the image left causes it to break out of, and thus not be enclosed by, the DIV. I attempt to remedy this by including another "clear: left" DIV before closing the containing DIV. This only works if the "clear: left" DIV has content, and not if it is empty. IE 5.5 clears the empty div. You can work around this by including an nbsp as the content, but this adds a very unnatractive extra blank line below the real content of the DIV. You can set the font-size of the nbsp to zero, removing the extra space, but then you are getting well into hack territory. Tested in Build ID 2000071408 under Windows 2000. I have been told behavior is cross platform.
Keywords: css1
Hmmm... I wonder if this has something to do with margin collapsing. Clear is supposed to increase the top margin so the element clears floats. Margins collapse through empty elements. I wonder if we're doing the collapsing before we do the clearing? Is it possible to do the reverse? (I think not.) If not, I'd think the only solution would be to propogate the 'clear'...
Summary: An empty DIV "clear: left" does not clear a "float: left" image → [MARGIN-C]An empty DIV "clear: left" does not clear a "float: left" image
Interesting Note: If you place more content inside the containing DIV /after/ the empty "clear: left" DIV, the content will be cleared, and all will be contained. I know margins should collapse, but I don't think this is a margin issue, because we are really talking about containment here. My understanding is that collapsing margins relates to how a containing box would arrange it's children with respect to /each other/. This deals with how a box arranges /itself/ with respect to it's children. Should the box itself collapse through an empty child element? And if so, why does content following the empty element still clear?
The CSS statement on collapsing margins is simple: any ajdacent margins collapse. This means that margins collapse in the following ways: * bottom-margin of one element with top-margin of its sibling * top(bottom)-margin of parent and top(bottom)-margin of first(last) child * top-margin and bottom-margin of empty element (or element with only out-of-flow children) * combinations of the above
Yeah...sure, but I don't think this is a margin issue. The problem here isn't with the relationship between adjacent boxes, or even with out-of-flow boxes. The problem here is with their relationship with their parent box. Now, the CSS spec clearly shows how an out-of-flow box is not contained by it's parent box. In this case, the parent box ignores the out-of-flow children, and collapses to the bottom of the in-the-flow children. Now, if you clear an in- the-flow child around the out-of-flow child, the parent should contain that child, because it is in-the-flow. In this case, the child we are clearing is empty. It seems logical to me that since text following an empty cleared left box is also cleared left (3rd attachment), that this implies that the cleared empty element does in fact extend the end of the normal flow to below the out- of-flow box, and thus should be contained by the parent.
Actually, I misread the original bug. This bug is invalid for the reasons I described above. The top-margin from the 'clear' should collapse with the top-margin of the empty DIV and the bottom-margin of the containing DIV and end up outside of the containing DIV. This is what is happening, so this bug is technically INVALID. If you give the empty DIV a 'border-top: 0.1px solid transparent' or a 'height: 0.1px' that should do what you want. However, I agree with you that this behavior is somewhat surprising, so we should ask the CSS WG if a 'top-margin' increased by 'clear' should be prohibited from collapsing with the bottom-margin of the same element. This may (or may not) be somewhat difficult to implement. Implementing it could risk introducing incremental reflow bugs. Confirming and assigning to attinasi to see what he thinks.
Assignee: clayton → attinasi
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: css1css3
Whiteboard: should ask CSS WG if spec should be changed (we are correct now)
I'm afraid I don't understand what you mean by "The top-margin from the 'clear' should collapse with the top-margin of the empty DIV". The empty DIV is the one set 'clear'. ? I would think that nothing inside the normal child flow would ever end up outside it's parents box?
Thanks for all of the discussion, information and for assigning this to me. I have never seen the 'clear' property until now, so I am a bit behind. First, IE5 (Win) and Opera4 both extend the blue box to include the image, just like the reporter has suggested it should. Also, if I assign min-height:1px to the clear'd div then Mozilla extends the outer div to include it as well (just like if I give it a border or otherwise do something to give it a non-zero height). I looked at the frames we generate for the failing portion of the testcase and the problem appears to be that the clear'd div has a height of 0, so we are probably assuming that the containing div does not need to include that frame in its bounds. When the min-height:1px is used then there is a ipx (15-twip) height on the clear'd div and the containing div takes ir into account when its size is computed. Also, when there is text after the clear'd div then the containing div has to include that text in its size calculation so the containing div is sized correctly as well. I think this really is a layout problem: namely the calculation of the size of the containing div needs to take into account the clear'd div, even when it has a height of 0. I'm as unfamiliar with the block layout code as I am with the clear property, however this is a good opportunity to dive in and see how that calculation is happening. The discussion of the top margin collapsing onto the bottom margin of the same element escapes me, but I think this _may_ be a different problem anyway... Finally, isn't this really a css2 bug ('clear' is described in the css2 spec)?
Status: NEW → ASSIGNED
Clear is a CSS1 property. http://www.w3.org/TR/REC-CSS1#clear The test cases are valid CSS1.
Chris: David is right. At the bottom of the second case in the attachement, the following margins are adjacent (touching, with no content between them): margin-top of div with 'clear': enough required to clear image margin-bottom of div with 'clear': 0 bottom of containing div: 0 These three margins are collapsed into one, with a dimension the same as required to clear the image (since that is the biggest of the three). That margin is then carried out to the outermost block (the containing DIV). This is why the text after the containing DIV *does* clear the DIV. Note that the div with 'clear' actually DISAPPEARS since it has no height. It does not go beyond its container, it actually goes nowhere at all. (Having said that, in CSS elements are quite able to overflow their parents. In fact, CSS2 has a whole property devoted to this, aptly named 'overflow'.) I'm marking this INVALID. It is correct CSS1. If CSS3 wants to provide more ways around this (in addition to the existing ways of adding transparent borders, tiny heights, and so on) then that is another issue for a later product.
Status: ASSIGNED → RESOLVED
Closed: 25 years ago
Resolution: --- → INVALID
Target Milestone: --- → Future
You are right, I am wrong, my bad, sorry for the confusion. The final word: http://www.w3.org/TR/REC-CSS2/box.html#collapsing-margins "In this specification, the expression collapsing margins means that adjoining margins (no padding or border areas separate them) of two or more boxes (which may be next to one another or nested) combine to form a single margin." The key word in that sentence being /nested/. Just to note the source of my confusion: http://www.w3.org/TR/REC-CSS2/visuren.html#block-formatting "In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block boxes in a block formatting context collapse." Note how it (confusingly/incorrectly?) says /sibling/ boxes. And for anyone else who may be reading this because they are having a similar problem....the purest (purist :-) method I can find to achieve the desired containment is to give the containing DIV some padding, which Mozilla will (correctly) NOT collapse it's margin through (into the top-margin created by the empty DIV inorder to clear the floated image [as Ian described]).
Whiteboard: should ask CSS WG if spec should be changed (we are correct now)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: