Separate stacking-context membership from layout/geometry ancestry - #807
Open
nicoburns wants to merge 11 commits into
Open
Separate stacking-context membership from layout/geometry ancestry#807nicoburns wants to merge 11 commits into
nicoburns wants to merge 11 commits into
Conversation
…ize) passes Guard inline child taffy layout writes behind RunMode::PerformLayout, snapshot/restore the Parley layout around measure passes, and only run the out-of-flow positioning pass on PerformLayout passes.
Update the taffy pin to the current stack-top rev (grid-area edge-case fixes and cache-invalidation tests). Hoisted out-of-flow boxes were appended to the end of their containing block's paint_children, painting them above every in-flow sibling. Insert them at their (paint level, tree order) position instead, so z-index:auto positioned boxes paint in tree order among positioned siblings (CSS 2.1 Appendix E step 8). Fixes grid-items-relative-positioned-containing-block-004/005/006.
Replace the pre-layout paint hoisting (HoistedPaintChildren with baked positions) with a post-layout stacking membership pass: - Taffy's OOF containing-block lists are kept, with an inverse oof_containing_block pointer; layout_parent is never repointed. - paint_geometry_parent() resolves geometry ancestry (containing block for out-of-flow boxes, layout parent otherwise). - resolve_stacking_contexts derives paint_children (in-flow only) and per-stacking-context entry lists from the structural tree, gated by stacking damage. z-index:auto positioned boxes are stacking containers (non-atomic); real stacking contexts are atomic. - Entries carry no baked geometry: paint and hit testing resolve entry offsets (and intermediate scroll clips) on demand by walking geometry chains to the common ancestor, handling fixed-position scroll exemption uniformly. - Hit testing traverses the same representation in reverse paint order.
…tacking context A fixed-position box inside a scrollable fixed-position box (or any stacked entry whose containing-block chain bypasses the stacking context root's overflow clip) must not be clipped or scrolled by it. Draw such entries outside the clip layer, keyed on whether the entry's geometry chain passes through the clipping node.
…ontexts; add paint-order tests
Contributor
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
staging-devin-ai-integration
Bot
force-pushed
the
devin/1787748926-taffy-oof-hoisting-latebound
branch
from
August 29, 2026 13:24
4f6fbef to
89c20f9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the baked-position OOF paint hoisting (from the base branch) with a browser-like architecture that keeps three relationships separate: structural/layout ancestry (
layout_parent/layout_children, never mutated for paint), Taffy containing-block geometry (hoisted_children+ new inverseoof_containing_block), and paint order (a new derived stacking structure).Stacking membership (
layout/stacking.rs, run post-layout, gated bySTACKING_DAMAGE):paint_children(in-flow + floats only) and, if it's a real stacking context, aStackingContext { entries, negative_z_count }of its stacked descendants.Node::is_stackedvsNode::is_stacking_context_rootdistinguishz-index: autostacking containers (positioned boxes that contribute an entry but whose stacked descendants promote into the same enclosing context) from atomic real stacking contexts (non-auto z-index, opacity/filter/mask/clip-path, transform-ish properties viaestablishes_fixed_containing_block, mix-blend-mode, isolation, sticky/fixed, CSS animations).Geometry at paint time (no baked positions):
Node::paint_geometry_parent()= OOF containing block if out-of-flow, elselayout_parent.Node::stacked_entry_offset()resolves an entry's offset dynamically by walking geometry-parent chains from the entry and the stacking-context root to their common ancestor, accumulating layout locations, scroll offsets, and intermediate overflow clips.stacked_entry_escapes_clip()lets entries whose geometry chain bypasses a clipping stacking context (e.g. a fixed box inside a scrollable fixed ancestor) paint outside that ancestor's clip layer.Painting/hit testing:
blitz-paintdraws negative entries before content and non-negative entries after (draw_stacked_entriessplit onnegative_z_count);hit_innertraverses the exact same entries in reverse. The old hoisted-paint-children plumbing,layout_parentrepointing inattach_hoisted_children, and fixed-scroll hit-test special cases are removed.Also fixes flex/grid
ordersorting to ignore out-of-flow children (they aren't flex/grid items, perflexbox-paint-ordering-003.html).WPT
vs the base branch:
css-position+5,css-flexbox+3,css-grid+1,CSS2/positioning+4,css-transforms+4/-1,CSS2/zindexandCSS2/absposunchanged. The one new failure,css/css-transforms/perspective-split-by-zero-w.html, is a pre-existing preserve-3d/perspective rendering limitation that was previously masked: the test's reference hides a red patch under a 3D-transformed div that Blitz can't fully render; the old code incorrectly painted the ref's negative-z patch below the canvas background, making test and ref equally wrong.Tests
New
paint_order.rscases: abspos under an opacity ancestor that is not its CB keeps the opacity effect; negative-z abspos paints below in-flow sibling content. Existingoof_dynamic_cb.rssuite passes.Link to Devin session: https://dioxus.staging.devinenterprise.com/sessions/2e5b5e83db014e14be353d6e89c14433
Open in Devin Desktop: https://dioxus.staging.devinenterprise.com/desktop/session/2e5b5e83db014e14be353d6e89c14433?variant=devin-insiders
Requested by: @nicoburns
WPT results
138 newly passing, 44 newly failing (net +94).
Full diff (182 changed tests)
Generated by the WPT workflow.