Retain stacking-context membership for out-of-flow paint - #806
Closed
nicoburns wants to merge 5 commits into
Closed
Conversation
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/1787757603-retained-stacking-contexts
branch
from
August 26, 2026 17:01
8d1b069 to
9da4ddb
Compare
staging-devin-ai-integration
Bot
force-pushed
the
devin/1787757603-retained-stacking-contexts
branch
from
August 26, 2026 17:04
9da4ddb to
f8de72a
Compare
Out-of-flow boxes found while laying out inline content were emitted as
OOF candidates of the IFC root and bubbled to the nearest positioned
Taffy node. A positioned (or filtered) non-atomic inline between them is
not a Taffy node, so it was skipped and the box landed on an outer block
or the ICB. With the stretched-link pattern (a{position:relative} +
a::after{position:absolute;inset:0;z-index:1}) this produced a
viewport-sized invisible overlay that swallowed hover/hit-testing for
the whole page (e.g. the header links on examples/assets/bbc.html).
Inline layout now walks the inline ancestor chain of each out-of-flow
inline box. If an ancestor within the IFC establishes the containing
block, the candidate is recorded with a positioning area spanning the
ancestor's first to last fragment box (CSS 2.1 §10.1) and laid out in
the inline root's OOF pass via compute_oof_layout, re-homed to the
inline root for paint and hit-testing. Otherwise it bubbles as before.
Non-atomic inlines are not transformable, so only position, filters and
the corresponding will-change values make them containing blocks
(Node::inline_establishes_fixed_containing_block).
A stacking-context root with stacked entries is descended into for every hit test regardless of whether the point lies within its own box, since an entry may be positioned anywhere. The inline root's text hit-test then ran unguarded, and Parley's line lookup clamps out-of-range block offsets to the first/last line, so a point thousands of pixels above a heading such as `h4 { position: relative; z-index: 3 }` (with a hoisted abspos self-link) reported a glyph hit on that heading. On html.spec.whatwg.org this made every hit in the table of contents resolve to a heading in section 15, breaking hover and click on all TOC links.
Guard the text hit-test with the node's own box/overflow checks, as text can never lie outside them.
Replace the unconditional `has_stacked_content` escape in `hit_inner` with the node's `scrollable_overflow` rect, so hit testing no longer descends into every stacking context with entries (thousands of headings on the HTML spec) but only those whose painted bounds contain the point. For that to be sound the overflow rect must cover everything painted as part of the node's subtree. `resolve_transforms` now also unions in hoisted stacked entries and, via `escaping_oof_rect`, out-of-flow descendants whose containing block is an ancestor of the node (their geometry is otherwise only accounted for at the containing block). Also computes the context root's geometry origin once per hit test rather than once per entry, and defers the clip check for an entry until it actually reports a hit.
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
Alternative out-of-flow integration to #805 that keeps Taffy's finalized containing-block-relative geometry without rewriting Blitz's structural layout ancestry.
containing block -> OOF childrenand inverseOOF child -> containing blockgeometry relations, eliminating the full-treeattach_hoisted_childrenreconciliation pass.negative/auto_and_zero/positivelists only for explicitly dirty real stacking contexts. Collection follows structural/rendering order, traverses positionedz-index:autocontainers, and stops at nested real contexts.Validation:
cargo fmt --all,cargo clippy --workspace,cargo check --workspace, andcargo test --workspace.Link to Devin session: https://dioxus.staging.devinenterprise.com/sessions/b6714d5757fa4fa7b858caed09087cdb
Open in Devin Desktop: https://dioxus.staging.devinenterprise.com/desktop/session/b6714d5757fa4fa7b858caed09087cdb?variant=devin-insiders
Requested by: @nicoburns
WPT results
146 newly passing, 34 newly failing (net +112).
Full diff (180 changed tests)
Generated by the WPT workflow.