Repository navigation
Commit f5acb05
committed
Implement CSS 2.1 §8.3.1's real adjoining-margin-set algorithm
CssBox.MarginTopCollapse only ever resolved a pairwise Math.Max
between exactly two margins - never the full "adjoining margin set"
(collapsing to max(positives) + min(negatives), spanning an arbitrary
run of self-collapsing empty boxes and nested first/last-in-flow
children). This happened to match spec for same-sign pairs, which is
why 1 of 5 existing tests already passed; the other 4 were confirmed,
documented, [Ignore]d bugs from an earlier audit pass. All 5 now pass
for real.
CollapsedMarginTopChain/CollapsedMarginBottomChain walk forward
through an unblocked run of first/last-in-flow children (an inline or
inline-block parent can't participate - margin collapsing is a block-
formatting-context concept), so a nested child sits flush with its
parent instead of being pushed down twice.
CollectAdjoiningMarginsBeforeSibling walks backward through however
many self-collapsing (empty) siblings precede a box, reaching all the
way to the parent's own top margin if the whole run turns out
self-collapsing. CollapseMarginSet does the actual max(positives) +
min(negatives) fold. A floated box's own margin never participates in
collapsing at all (CSS 2.1 §8.3.1: floats are out of flow) - the
predecessor's trailing margin is still real space, but the float's
own margin sums on top rather than merging.
Two real, non-obvious bugs surfaced and got fixed while verifying this
against the full regression suite (not just the 5 targeted tests):
1. A "child sits flush, trust the parent already absorbed it" design
only works if CollapsedMarginTop tracks CUMULATIVE REALIZED
displacement (parent.CollapsedMarginTop + this box's own excess),
not each box's own semantic total in isolation - the first version
let a chain reaching the document root (which cannot itself move)
incorrectly "claim credit" for a value nothing had ever visually
applied, silently discarding real margins throughout ordinary
documents. Caught by the pixel-diff regression corpus, not the
targeted tests, which don't exercise a chain deep enough to hit it.
2. CssBoxProperties.ActualMarginTop resolves a percentage margin
against the box's OWN Size.Width (a pre-existing quirk, left alone
to avoid a wider blast radius) - safe once a box's own width has
actually been computed, but the forward-chain lookahead deliberately
reads a NOT-yet-laid-out descendant's margin, so Size.Width is still
the zero default there. New ResolveMarginTopForChain/
ResolveMarginBottomForChain resolve a percentage margin against the
containing block's already-known width instead, when read through
the lookahead specifically.
Also fixes CssBoxHr's own separate copy of the placement formula
(missed by the earlier self-collapsing-anchor fix, since it duplicates
rather than calls CssBox's placement code) to match.
Re-approves 6 pixel-diff baselines whose content legitimately changed
now that margin collapsing actually works: most visibly, a margin
percentage now correctly resolves against the containing block's
WIDTH (not height) per CSS2.1, and an auto-height parent with no
border/padding now correctly lets a sole child's top/bottom margins
collapse all the way through it rather than showing as visible space
inside the parent's own background - both are well-known, if
surprising, real CSS behaviors, confirmed by direct comparison against
each diff image before approving. MaxWidth/Iframes' diffs are network-
dependent broken-image-placeholder rendering (external URLs
unreachable in this environment for both the old and new baseline
capture) and don't reflect a functional change either way.1 parent 67bab41 commit f5acb05
10 files changed
Lines changed: 268 additions & 69 deletions
File tree
- Source
- HtmlRenderer/Core/Dom
- Test/HtmlRenderer.IntegrationTest
- Baselines
- BoxModel
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
51 | 55 | | |
52 | 56 | | |
53 | | - | |
| 57 | + | |
54 | 58 | | |
55 | 59 | | |
56 | 60 | | |
| |||
Loading
Loading
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
26 | 19 | | |
27 | 20 | | |
28 | 21 | | |
| |||
45 | 38 | | |
46 | 39 | | |
47 | 40 | | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | 41 | | |
55 | 42 | | |
56 | 43 | | |
| |||
64 | 51 | | |
65 | 52 | | |
66 | 53 | | |
67 | | - | |
68 | | - | |
69 | | - | |
70 | | - | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | 54 | | |
76 | 55 | | |
77 | 56 | | |
| |||
87 | 66 | | |
88 | 67 | | |
89 | 68 | | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | 69 | | |
101 | 70 | | |
102 | 71 | | |
| |||
115 | 84 | | |
116 | 85 | | |
117 | 86 | | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | 87 | | |
129 | 88 | | |
130 | 89 | | |
| |||
141 | 100 | | |
142 | 101 | | |
143 | 102 | | |
144 | | - | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | | - | |
151 | | - | |
152 | | - | |
153 | 103 | | |
154 | 104 | | |
155 | 105 | | |
| |||
0 commit comments