Closed pavpanchekha closed 1 month ago
Conclusions so far: LB creates an anonymous block box containing the orange/red floats. That anonymous box is what resets the collapsed-margin state. That box lays out its contents with an IFC; it's that IFC specifically that resets it.
Ok, further conclusions.
We're looking at this subtree of the layout tree:
BlockContainer (anonymous)
BlockContainer DIV#B
BlockContainer DIV#C
Both B
and C
are floating, and C
introduces clearance; that causes the IFC to call reset_margin_state
inside generate_line_boxes
in the Floating
case. Now to figure out why this is invalid to do.
(Point of pride: Cassius gets it right.)
Ok, got it, I think here's what happens in the spec (I'm using the CSS 2.1 spec which I'm not sure if it's still controlling). The #B
and #C
are placed into an anonymous block box, which creates an IFC, which creates a line box. Now consider the the rules for adjoining margins, here: https://www.w3.org/TR/CSS2/box.html#collapsing-margins
Two margins are adjoining if and only if:
- ...
- ... no line boxes ... separate them (Note that certain zero-height line boxes (see 9.4.2) are ignored for this purpose.)
So our anonymous block box does have line boxes separating its top and bottom, so the question is whether that is a "certain" zero-height line box:
Line boxes that contain no text, no preserved white space, no inline elements with non-zero margins, padding, or borders, and no other in-flow content (such as images, inline blocks or inline tables), and do not end with a preserved newline must be treated as zero-height line boxes for the purposes of determining the positions of any elements inside of them, and must be treated as not existing for any other purpose.
Our line box contains nothing at all so it qualifies. The other part that might worry us is:
Two margins are adjoining if and only if:
- ...
- ... no clearance ... separate them (Note that certain zero-height line boxes (see 9.4.2) are ignored for this purpose.)
But this isn't talking about clearance on floating elements, it's talking about clearance on in-flow children.
So my current thinking is that we don't need to reset the parent's margin state when we see a Floating box that introduces clearance? Only if some other element introduces clearance. Commenting that line introduces no test failures.
I found an issue on the Web Browser Engineering online book, on pages like http://browser.engineering/html.html, with floats and collapsing margins. Here's Chrome:
Here's Ladybird:
Note the different gap between the gray nav bar and the paragraph of text underneath. I've minimized it to this HTML:
On Chrome:
On Ladybird:
I'm going to try to solve it myself but figured I'd gotten far enough to file an issue.