Closed Bug 204831 Opened 21 years ago Closed 19 years ago

float absorbs clearing element's top margin

Categories

(Core :: Layout: Floats, defect, P2)

defect

Tracking

()

RESOLVED FIXED

People

(Reporter: hgoffin, Unassigned)

References

Details

(Whiteboard: (py8ieh:make sure css2.1 test suite contains tests for all three damowmow cases))

Attachments

(4 files)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4b) Gecko/20030428 Mozilla Firebird/0.6
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4b) Gecko/20030428 Mozilla Firebird/0.6

A floated element followed by a clearing element is displaced vertically by the
top margin of the clearing element.  Should this happen?  CSS spec seems unclear
to me on this point, but Mozilla's interpretation does not match with my
common-sense.

See the following attachment for an example.

Reproducible: Always

Steps to Reproduce:
1. View attached test case
2. Toggle second DIV using javascript links
3. Observe position of first DIV
Actual Results:  
Floated element is vertically displaced

Expected Results:  
Floated element shouldn't move
Attached file testcase
There are already bugs on this problem.
Assignee: dbaron → float
Component: Style System → Layout: Floats
Whiteboard: DUPEME
Which other bugs are on this problem? This is the only report that I could find
searching for this bug.

I think it's definitely a bug. IE does it right.
Determining the correct behavior requires a very careful reading of the text in
http://www.w3.org/TR/2003/WD-CSS21-20030905/visuren.html#flow-control and other
(recently revised) parts of the spec.
The correct behavior is explicitly stated by http://www.w3.org/TR/2003/WD-CSS21-
20030905/visuren.html#flow-control -- "8. A floating box must be placed as high 
as possible."

Mozilla's handling of the testcase is in direct violation of this, since the 
float is shifted down by the top margin of the following clearing block.  
Further, I believe that the box placement is fundamentally incorrect, 
disregarding any changes or clarifications to CSS float rules.  Observe that 
the margin of each DIV should be 12 pixels and that the BODY element has no 
margin.  The floated DIV is not contained by anything except the BODY element 
and yet is placed 24 pixels from the top of the page.  Hence my reason for 
opening this bug (which is NOT a dupe): floated DIVs absorb the top margin of a 
subsequent clearing element.
It's not nearly that simple.

Section 8.3.1 describes collapsing margins.  Section 10.6.3 describes where the
top is of an element whose margins collapse with its parent -- below the
collapsed margin.  If the margins of the DIV collapse with the margins of the
BODY (and whether they do depends on the details of the wording of the
definition of 'clear', which I haven't fully digested yet), then the float
should be lower because section 9.5.1, rule 4, says "A floating box's outer top
may not be higher than the top of its containing block."
Oops, the point of the margin collapsing is not just DIV collapsing with BODY,
but DIV collapsing with BODY and HTML.
Sorry but I'm still not understanding your interpretation.  The testcase has no 
margins that could possibly collapse.  Neither the HTML nor BODY elements have 
margins, only the two DIVs which are adjacent, and floated margins never 
collapse.  Further, 9.5.2 makes it perfectly clear that a clearing block is to 
be placed in flow, and them displaced vertically so that its outer top is below 
the outer bottom of the floats.  Thus there should be 24px of space between the 
float and the clear and 12px of space above it.

Instead, there is 24px of space above the float and only 12px of space below.  
Obviously the top margin of the clearing element is pushing the floated element 
down, which is not correct.  I simply cannot understand how any interpretation 
of CSS says that that is acceptable.  If you're sure that this matches your 
understanding of CSS, could you please give me a more specific example from the 
spec?
Are you trying to say that the clearing DIV's 12px margin is being collapsed 
with the BODY and HTML elements' 0px margins, and transferred up to them?  
Because that would make no sense at all.  A contained element can collapse its 
margins with the container but it cannot /extend/ the margins of its 
container ... can it?  That sounds very rediculous.

Also, that DUPEME in the whiteboard status has got to go.  I searched for 2 
weeks before I filed this bug and I've casually searched for 4 months 
afterwards trying to find a dupe.  I could not find any bugs related to the 
handling of vertical margins with respect to floats and clearing blocks.
Whiteboard: DUPEME
Sorry for filing three seperate additions to this bug, but after re-rereading 
the spec, I finally understand your position on adjoining elements and 
collapsing margins.  However, notice the wording of the main portion of 
9.5.2: "The clearance dimension is introduced as a dimension above the margin-
top of an element that is used to push the element vertically (typically 
downward)".

So the presense of a clearance dimension introduces a boundary between the BODY 
margin and the DIV margin, and those margins can not be collapsed.  It would 
make no sense to collapse the margins and transfer the clearance dimension to 
the BODY element, because the very thing that you are trying to clear is a 
child of the BODY element.
Blocks: 220114
The "main" DIV's top margin starts at the end of the body's top padding. The
"main" DIV's border and content are clear after the float.
"clear:left
    The clearance of the generated box is set to the amount necessary to place
the top border edge is below the bottom outer edge of any left-floating boxes
that resulted from elements earlier in the source document."
"Vertical margins between a floated box and any other box do not collapse"

Note the attachment: The clear doesn't effect the margin at all.
My reading (and, er, writing, in this case, heh) of the specs indicate that this
is indeed a valid bug.
   http://www.damowmow.com/playground/bugs/204831/003.html (renders correctly)
   http://www.damowmow.com/playground/bugs/204831/001.html (renders incorrectly)

I would have thought there'd be a dupe, but I couldn't find one... maybe dbaron
is right, my belief that we've found all the float bugs is naive. :-)
Status: UNCONFIRMED → NEW
Ever confirmed: true
I don't see what's wrong with our layout of
http://www.damowmow.com/playground/bugs/204831/001.html and I also don't see how
it's relevant to this bug (where's the 'clear'?).
My bad. I suck.

Yes, 001 is correct, because the top of the float is below the collapsed margins 
in 001 case, but in the 003 case, there aren't any to collapse.

The clear is covered by 002, which shows that it in fact is not needed to 
trigger the so called bug.

Which, in fact, is indeed not a bug.

->INVALID.
Status: NEW → RESOLVED
Closed: 21 years ago
Resolution: --- → INVALID
No, I think it actually is valid, and that's one of the reasons I didn't like
the way the clearance proposal worked.
Status: RESOLVED → REOPENED
Resolution: INVALID → ---
Oh right. The discontinuity case. Yeah. So, er, why don't I shut up, and let you 
all get on with this without my slapdash confirms and invalidates. I think that 
would be best all round, don't you?
Whiteboard: (py8ieh:make sure css2.1 test suite contains tests for all three damowmow cases)
Comment #8 is wrong.
9.5.2 states that the top border edge (not its outer top) is below the outer
bottom of the floats.
However it also says "The clearance dimension is introduced as a dimension above
the margin-top of an element that is used to push the element vertically".
OK, so the clearing element is pushed down the correct amount, but does that
mean that the float's position from top should be recalculated as well? The spec
is a little foggy to me, I'm not sure if it actually states that the clearing
element's top margin should be completely colapsed (causing the float to move
up). But it clearly does NOT say that the clearing block's margin is below the
float's.
Oops, wait, see the image in 9.5, just above 9.5.1 :
"...causes the second paragraph to be "pushed down" to a position below the
float — its top margin expands to accomplish this".
That makes it clearer to me, but still doesn't answer the question. Obviously
the clear is calculated after the margin's are calculated. And since a margin
was specified, it's being used, I'm not so sure this is a bug.
The diagram at the end of 9.5 is wrong. I have added it to the CSS2.1 last call 
issues list.


> OK, so the clearing element is pushed down the correct amount, but does that
> mean that the float's position from top should be recalculated as well?

Yes, see section 8.3.1 (upon which the positioning of the float matters), which 
is clear about the fact that clearance stops margin collapsing. Once you add 
clearance, you have to then recalculate the margins.


> But it clearly does NOT say that the clearing block's margin is below the
> float's.

No, the clearing block's top _border_ edge should be flush with the bottom 
margin edge of the float -- the top margin of the clearing block will typically 
be under the float (and can, in some strange situations, end up higher than the 
earlier block's bottom margin edge, with the clearance being negative).
I'm looking at this being rendered in visual order, not logical order. I don't
see where http://www.w3.org/TR/CSS21/box.html#collapsing-margins implies that
non-collapsed margins should be recalculated, (but then I can't access the links
above, perhaps you see a newer version). I'm not arguing against it here, but
only that a negative margin after a clear could be undesirable.
I don't understand comment 21. The place in 8.3.1 that says it should be 
recalculated is the place where it mentions clearance (it's implied -- if you 
don't recalculate it, then those parts of the spec become meaningless). If you 
disagree with what the spec says, www-style@w3.org is the appropriate forum.
The WG discussed this. We decided that the text was clear enough. Clear doesn't
cause things to get repositioned, margin collapsing does.
I had a dream... well that didn't get me anywhere, but it drove me to write some
test pages that I feel illustrate this bug better. I stuck them here so that I
could link them together:
http://test.bigsleep.net/Bugz/clearfloat1.html
So take a look, you might find it interesting:
Example #1 is basically another version of the above testcase.
Example #2 illustrates an apparent "fix" to the problem by adding a block before
the floated block. I don't see anything wrong with #2, even changing the
properties doesn't mess it up.
Example #3 shows how clearance effects margin collapse (I wrote this one in my
sleep), and doesn't seem to have anything to do with this bug.
Example #4 is #3 with the "fix" added.
Example #5 may be the best one, as it shows how things get really messed up. It
starts with a border around the float's parent: which seems to "fix" the bug,
but changing the border to 0 width not only shows the float's top offset is
wrong, but is also a good example of Bug 220114 , at least on my system the
background and border are badly rendered when elements move around. In fact the
backgroud in the top and bottom margins goes transparent.
In my comments in 21 I was trying to understand what Mozilla was doing by
looking at the visual rendering order, but that doesn't apply because it is not
consistant: Example #1 and #2 should be the same. I wasn't disagreeing with
anything - a clear explanation is all that is necessary.
Lowering priority to P4 because this bug is rapidly becoming incomprehensible,
and what should really happen here is implementation of the CSS2.1 clearance
model (once it's stable) rather than fixing one bug at a time.

(In a well-written bug, the reader should be able to tell in 30 seconds what
behavior would need to change for the bug to be considered fixed.)
Priority: -- → P4
Actually, never mind.  Comment 0 and comment 1 are actually reasonably clear. 
But don't expect people to read the rest of the bug in detail.  (Do all those
comments really cover the issue described in comment 0 and comment 1?)
Priority: P4 → P2
Really, I started this bug back 6 months ago for one specific issue: float
position is improperly calculated when a clearing element has a top margin.

The behavior in Mozilla is currently that the float is displaced by the top
margin of the clearing element.  The expected behavior is that the float is not
displaced.

All the chatter and back-and-forth on this bug comes from obscure definitions,
problems, etc. raised by the complicated wording of the CSS2.1 spec.  But this
was a common-sense issue long before CSS2.1 ever came around.  A clearing
element should not displace the very block it is trying to clear.  This was not
expressly stated as part of the CSS spec before.  CSS2.1's "clearance" is just a
mechanism to finally agree with common sense.  

So, a float should not be displaced by the next block's margin.  That is what
should be fixed when this bug is closed.  Exactly how this is achieved, with CSS
clearance or whatever, is not important to me.  The original CSS specs did not
explicitly cover this case; Internet Explorer renders the float as an author
would expect.  Mozilla's approach does not make any sense and that is why this
bug was opened.
I posted my examples because I thought it clearly showed how the float's top
offset changes depending on whether it's the first child or second child, or
whether it's parent has a border or not. Clearing the next block doesn't seem to
effect anything (removing it does).
This inconsistancy I would think is the important issue. I don't see this
pointed out anywhere else. I suppose I should have made this clearer in my last
post.
First of all, the original test case in comment 0 and comment 1 is definately a
bug.  It violates CSS 2.1's clearance rules.  But all the brainstorming over
this bug exposes a much larger problem within the CSS spec, which I will detail
here.  (This is what Ric's testcases from comment 12 and comment 24 are exposing.)

Let's say we have a BODY containing a DIV (#1) which is floated, followed by a
DIV (#2) which is not floated.  The BODY is explicitly given a 10px top margin.
 DIV #1 is explicitly given a 10px margin on all sides.  DIV #2 is explicitly
given a 40px margin on all sides.  What should happen?

From any sane point of view, DIV #1 should start 20px from the top of the canvas
(no collapse, 10+10->20) and 10px from the left (no collapse, 0+10->10).  It
should overlap with DIV #2, which should start at 40px down (collapse,
10,40->40) and 40px left (collapse, 0,40->40).

From the CSS spec's and Mozilla's point of view, DIV #2 is adjacent to the BODY
and so the margins are collapsed and folded INTO THE BODY.  So now the BODY has
a 40px margin, and DIV #1 starts at 50px down (no collapse, 40+10->50) and 50px
left (no collapse, 40+10->50).

This is obviously not what the page author desires.  If he wanted DIV #1 to be
pushed inward and downward by 40px, he would have set the margin of the BODY to
40px/40px instead of 10px/0.  The margin of DIV #2 should collapse with the
margin of the BODY, but it should not be merged with the margin of the BODY when
calculating the position of DIV #1.

It gets even hairier.  If DIV #2 had the clear property set, DIV #1 would be
positioned at 10px/10px, because clearance prevents top margin collapse.  But
without the clear property, DIV #1 starts at 50px/50px.  This means that
clearance also affects the horizontal positioning of the float.  What a mess!

The correct behavior, IMO, is that DIV #1 should never be pushed down.  The
margins should be collapsed during computations for non-floated elements only. 
But I have no idea how to bring this up with the CSS working group.  Maybe
someone can give me some pointers by email?
This is not a useful forum for discussion of flaws in the CSS spec, for two reasons:

 1. We need to keep one issue per bug.  Otherwise it becomes impossible to use
bugs to track things that need to be fixed.  (What happens when the issue
discussed in 90% of the comments has been fixed?  Usually, we just mark the bug
as FIXED and ignore the other 10% of the comments, which can't be distinguished
from the first 90% without careful reading in the first place.)

 2. Changes to the CSS spec should be discussed on the www-style mailing list.

>From the CSS spec's and Mozilla's point of view, DIV #2 is adjacent to the BODY
>and so the margins are collapsed and folded INTO THE BODY.  So now the BODY has
>a 40px margin, and DIV #1 starts at 50px down (no collapse, 40+10->50) and 50px
>left (no collapse, 40+10->50).

This is incorrect when referring to the CSS spec's point of view, although it's
a recent change:

# When the rules above do not result in an exact vertical position, as may be
# the case when the float occurs between two collapsing margins, the float is
# positioned as if it had an otherwise empty anonymous block parent taking
# part in the flow. The position of such a parent is defined by the rules in
# the section on margin collapsing.

Note that the words "the rules above do not result ... may be the case" should
be removed.
Additional remark on testcase 1: If you reduce the margin-bottom of the div
elements to zero (margin: 12px 12px 0;), then there is no margin between fleft
and main div elements. Normally the maximum value of fleft's bottom margin and
main's top margin should be displayed.

If you add the style element "float: left" to the main div the additional then
the rendering is correct. Nice hack for Mozilla ":root #main {float: left}".
Depends on: 209694
I am experiencing the same, or very closely related problem. In my case I have 


1. a floated block
2. a cleared block with nested content that has a top margin

The margin on the content within the cleared block (2) generates a margin above
the floated block (1). This is clearly nonsensical.
WFM with Mozilla 1.8a6 build 2004112806 on WinNT4.
This is mostly fixed.
The first and third testcase are fixed by bug 209694.
In the second testcase ("Added option to set clear to none and back."), I can
still see a bug, however. 
When clicking on the "[Set Next Block Clear to None]" link and the "[Set Next
Block Clear to Left]" link, I would not expect the left block too become higher
(because the text on the first line gets cleared to the second line). This is
not what Opera7.54 is doing.
Added a slightly different testcase. In Moz 1.8a6 indeed the margin on the
clearing element doesn't push the float down anymore, but what happened to the
margin itself? It is just ignored as it seems which strikes me as odd.

Also maybe related (although I think it is more a rendering issue) is the
testcase from PPK at http://www.quirksmode.org/css/tests/moz_float.html
Got this bug on a page I was making, too. Hopefully it gets resolved, though 
it already means I can't use the solution I was thinking of since not many 
people use latest versions. IE gets it right, by the way.

Another wrapping div, this time due to Mozilla... :-)
(In reply to comment #35)
> Added a slightly different testcase. In Moz 1.8a6 indeed the margin on the
> clearing element doesn't push the float down anymore, but what happened to the
> margin itself? It is just ignored as it seems which strikes me as odd.
Crisp, I think that's a different bug. It would probably be wise to file a new
bug on this, and make it blocking bug 209694.

> Also maybe related (although I think it is more a rendering issue) is the
> testcase from PPK at http://www.quirksmode.org/css/tests/moz_float.html
This is a diffent bug, and an already known one. It's probably bug 41412.
Ok, I filed bug 282462 about the first issue mentioned in comment 35.
(In reply to comment #35)
Actually in this testcase, we are correct according to the spec, and IE and
Opera are wrong. I'll explain why in bug 282462.
(In reply to comment #34)
> In the second testcase ("Added option to set clear to none and back."), I can
> still see a bug, however. 
> When clicking on the "[Set Next Block Clear to None]" link and the "[Set Next
> Block Clear to Left]" link, I would not expect the left block too become higher
> (because the text on the first line gets cleared to the second line). This is
> not what Opera7.54 is doing.

Martijn, can you file a new bug about that issue if it still exists and looks
like a real bug? I'm closing this one down.
Status: REOPENED → RESOLVED
Closed: 21 years ago19 years ago
Resolution: --- → FIXED
Well, I filed bug 297844 for that, but in hindsight I think it is an invalid bug
and I think Mozilla is doing the correct thing here (for all testcases) and in
bug 297844. See bug 297844, comment 1.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: