Skip to content

Integrate Taffy out-of-flow hoisting support - #805

Open
nicoburns wants to merge 8 commits into
mainfrom
devin/1787748926-taffy-oof-hoisting-latebound
Open

Integrate Taffy out-of-flow hoisting support#805
nicoburns wants to merge 8 commits into
mainfrom
devin/1787748926-taffy-oof-hoisting-latebound

Conversation

@nicoburns

@nicoburns nicoburns commented Aug 26, 2026

Copy link
Copy Markdown
Member

Summary

Integrates Taffy's browser-style out-of-flow (OOF) hoisting (dispatcher-owned pass) into Blitz. Depends on the Taffy PR stack (DioxusLabs/taffy stack #1173: DioxusLabs/taffy#1140 / DioxusLabs/taffy#1170 / DioxusLabs/taffy#1171 / DioxusLabs/taffy#1172) landing first — the taffy dependency is pinned to rev = "4da30115" (stack top, includes the late-bound static-position representation, grid-area edge-case fixes and cache-invalidation tests).

This PR replaces #763 (closed; branch preserved as backup/taffy-oof-hoisting-prelatebound). The only change is the taffy pin bump to the late-bound stack: Blitz's inline emitter already uses StaticPosition::from_edge, which maps unchanged onto the new area+alignment representation.

Key changes:

  • Style mapping (stylo_taffy::convert::position): static → Position::Static, fixed → Position::Fixed (previously Relative/Absolute).
  • Tree traits (blitz-dom/layout/mod.rs): per-node hoisted_children storage via set_hoisted_children/add_hoisted_children; RoundTree::{is_hoisted, hoisted_child_count, get_hoisted_child_id}; LayoutContainingBlock impl (get_oof_item_style, get_detailed_layout_info); compute_oof_layout runs in the compute_cached_layout cache-miss closures (normal + block dispatch), on PerformLayout passes only; forwarded through TableTreeWrapper.
  • oof_claims: positioned elements claim absolute candidates; elements establishing a fixed containing block (transform/translate/rotate/scale/perspective, filter/backdrop-filter, will-change: transform/perspective + fixpos bits, contain: layout/paint, container-type != normal) claim both (Node::establishes_fixed_containing_block).
  • Inline layout (layout/inline.rs): the local layout_abspos_child routine is removed; inline layout now emits OofCandidates (with hypothetical-box static positions, RTL-aware inline-level edges) and an OofPositioningArea, bubbling candidates from float/inline-block subtrees. Measure (ComputeSize) passes no longer mutate persistent state: child Taffy layouts are only written on PerformLayout, and the Parley layout is snapshotted/restored around measure passes (fixes a pre-existing cache-clobber bug where a hover restyle could leave measure-time line breaks in painted output — reproduced on GitHub's repo page; regression test in tests/blitz-tests/tests/measure_clobber.rs).
  • Detailed layout info: ElementData.detailed_grid_info: Option<Box<DetailedGridInfo>>detailed_layout_info: DetailedLayoutInfo, needed for grid-area-based OOF positioning of non-direct grid descendants.
  • Coordinate consumers: since a hoisted box's Layout.location is now relative to its containing block's border box, a post-layout pass (BaseDocument::attach_hoisted_children) repoints each hoisted box's layout_parent at its CB (so absolute_position, offsetLeft/Top etc. accumulate through the CB chain) and splices hoisted boxes into the CB's paint_children at their (paint level, tree order) position per CSS 2.1 Appendix E step 8 (z-indexed hoisted boxes are instead pushed into the nearest ancestor stacking context, matching the existing z-index hoisting in flush_styles_to_layout; boxes with an intermediate atomic paint-effect ancestor — opacity/filter/clip-path/mask — are painted inside that ancestor's effect layers with a compensated offset). OOF boxes remain in their DOM parent's paint list when the parent is itself their CB (preserving in-tree paint order) and are skipped otherwise. Paint and hit-testing cancel the CB's scroll offset for position: fixed children — using the viewport scroll when the CB is the root element (fixed boxes don't scroll with the document); scrollable-overflow resolution (resolve_transforms) accounts OOF boxes at their CB instead of their DOM parent.
  • Dynamic invalidation tests (tests/blitz-tests/tests/oof_dynamic_cb.rs): toggling containing-block-establishing properties (transform/will-change/filter/contain/position, via style attributes and :hover restyles), DOM insertion/removal of fixed boxes, display:none toggles, and content changes inside hoisted subtrees, all under incremental layout.

WPT results (before → after, tests fully passing)

Suite Before After Delta
css/css-position 54/382 56/382 +2
css/CSS2/positioning 354/578 388/578 +34
css/CSS2/abspos 9/32 10/32 +1
css/css-flexbox/abspos 53/70 54/70 +1
css/css-grid/abspos 103/214 112/214 +9
css/css-display 68/341 68/341 0

Net across these suites: 55 newly passing, 8 regressed (+47 overall). The paint-order splice + taffy stack-top bump added a further net +3 on css/css-grid (grid-items-relative-positioned-containing-block-004/005/006 now pass) with no css-position regressions.

Known regressions (grouped)

  1. Paint order of OOF boxes hoisted past their DOM parent, cross-hierarchy cases (grid-items-relative-positioned-containing-block-003, position-relative-016, position-sticky-stacking-context-002, CSS2/backgrounds/background-position-002): the tree-order splice fixes ordering within one containing block's paint list, but a box hoisted to a distant CB (e.g. the ICB) still paints after the entire subtree containing a later positioned z-index:auto box, because Blitz paints hierarchically. A correct fix needs CSS 2.1 Appendix E step-8 semantics (collect all positioned z-index:auto descendants at the stacking-context level, painted after in-flow content in tree order) — deferred pending a design that doesn't hurt paint performance.
  2. Positioned inline boxes as containing blocks (2 tests, nested-inline-abspos-child*): a position:relative inline span is not a Taffy node, so it cannot claim candidates; abspos boxes inside it now bubble past it. The old code positioned them relative to the inline root, which happened to pass these tests.
  3. Anchor-positioning tests (anchor-scroll-fixedpos-003/004, anchor-scroll-nested, position-visibility-anchors-visible-in-overflow, filter-cb-abspos-inline-002/003): false passes on main (both test and ref mis-rendered); the branch now renders the refs correctly so they fail honestly. They need anchor() support (and inline CBs) to pass.

Testing

  • cargo fmt --all, cargo clippy --workspace (clean), cargo check --workspace, cargo test --workspace (all pass).
  • WPT via the wpt runner on this branch vs main, including focused reruns of css/css-grid/** and css/css-position/** before/after the paint-order splice.

Link to Devin session: https://dioxus.staging.devinenterprise.com/sessions/65c5463061c8403bade7888271d5eeb4
Open in Devin Desktop: https://dioxus.staging.devinenterprise.com/desktop/session/65c5463061c8403bade7888271d5eeb4?variant=devin-insiders
Requested by: @nicoburns

WPT results

151 newly passing, 37 newly failing (net +114), 15 other status changes.

Full diff (203 changed tests)
+ Fail => Pass css/CSS2/abspos/adjacent-to-relpos-inline-in-inline-that-had-block.html
+ Fail => Pass css/CSS2/abspos/adjacent-to-relpos-inline-that-had-block.html
+ Fail => Pass css/CSS2/abspos/static-inside-inline-002.html
+ Fail => Pass css/CSS2/backgrounds/background-bg-pos-204.xht
- Pass => Fail css/CSS2/backgrounds/background-position-002.xht
+ Fail => Pass css/CSS2/backgrounds/background-root-023.xht
+ Fail => Pass css/CSS2/box-display/containing-block-007.xht
+ Fail => Pass css/CSS2/box-display/containing-block-008.xht
+ Fail => Pass css/CSS2/box-display/containing-block-009.xht
+ Fail => Pass css/CSS2/box-display/containing-block-010.xht
+ Fail => Pass css/CSS2/floats-clear/clear-applies-to-012.xht
+ Fail => Pass css/CSS2/floats-clear/clear-applies-to-014.xht
+ Fail => Pass css/CSS2/floats-clear/clear-clearance-calculation-004.xht
+ Fail => Pass css/CSS2/floats-clear/clear-clearance-calculation-005.xht
+ Fail => Pass css/CSS2/floats-clear/floats-019.xht
+ Fail => Pass css/CSS2/generated-content/before-after-positioned-002.html
+ Fail => Pass css/CSS2/generated-content/before-after-positioned-003.html
+ Fail => Pass css/CSS2/margin-padding-clear/margin-collapse-037.xht
+ Fail => Pass css/CSS2/positioning/absolute-non-replaced-width-026.xht
+ Fail => Pass css/CSS2/positioning/abspos-014.xht
+ Fail => Pass css/CSS2/positioning/abspos-015.xht
+ Fail => Pass css/CSS2/positioning/abspos-016.xht
+ Fail => Pass css/CSS2/positioning/abspos-017.xht
+ Fail => Pass css/CSS2/positioning/abspos-018.xht
+ Fail => Pass css/CSS2/positioning/abspos-022.xht
+ Fail => Pass css/CSS2/positioning/abspos-026.xht
+ Fail => Pass css/CSS2/positioning/abspos-containing-block-005.xht
+ Fail => Pass css/CSS2/positioning/abspos-containing-block-006.xht
+ Fail => Pass css/CSS2/positioning/abspos-overflow-001.xht
+ Fail => Pass css/CSS2/positioning/abspos-overflow-002.xht
+ Fail => Pass css/CSS2/positioning/abspos-overflow-003.xht
+ Fail => Pass css/CSS2/positioning/abspos-overflow-004.xht
+ Fail => Pass css/CSS2/positioning/abspos-overflow-005.xht
+ Fail => Pass css/CSS2/positioning/abspos-overflow-006.xht
+ Fail => Pass css/CSS2/positioning/abspos-overflow-007.xht
+ Fail => Pass css/CSS2/positioning/abspos-overflow-008.xht
+ Fail => Pass css/CSS2/positioning/abspos-overflow-009.xht
+ Fail => Pass css/CSS2/positioning/abspos-overflow-012.xht
+ Fail => Pass css/CSS2/positioning/dynamic-top-change-002.xht
+ Fail => Pass css/CSS2/positioning/dynamic-top-change-003.xht
+ Fail => Pass css/CSS2/positioning/dynamic-top-change-004.xht
+ Fail => Pass css/CSS2/positioning/left-applies-to-009.xht
+ Fail => Pass css/CSS2/positioning/left-applies-to-012.xht
+ Fail => Pass css/CSS2/positioning/left-applies-to-013.xht
+ Fail => Pass css/CSS2/positioning/left-applies-to-014.xht
+ Fail => Pass css/CSS2/positioning/position-fixed-007.xht
- Pass => Fail css/CSS2/positioning/position-relative-016.xht
+ Fail => Pass css/CSS2/positioning/position-static-001.xht
+ Fail => Pass css/CSS2/positioning/right-applies-to-009.xht
+ Fail => Pass css/CSS2/positioning/right-applies-to-012.xht
+ Fail => Pass css/CSS2/positioning/right-applies-to-013.xht
+ Fail => Pass css/CSS2/positioning/right-applies-to-014.xht
+ Fail => Pass css/CSS2/positioning/top-applies-to-009.xht
+ Fail => Pass css/CSS2/positioning/top-applies-to-012.xht
+ Fail => Pass css/CSS2/positioning/top-applies-to-013.xht
+ Fail => Pass css/CSS2/positioning/top-applies-to-014.xht
+ Fail => Pass css/CSS2/tables/separated-border-model-007.xht
+ Fail => Pass css/CSS2/tables/separated-border-model-008.xht
+ Fail => Pass css/CSS2/tables/separated-border-model-009.xht
+ Fail => Pass css/CSS2/visuren/anonymous-boxes-001b.xht
+ Fail => Pass css/CSS2/visuren/inherit-static-offset-001.xht
+ Fail => Pass css/CSS2/visuren/inherit-static-offset-002.xht
+ Fail => Pass css/CSS2/visuren/inherit-static-offset-003.xht
+ Fail => Pass css/CSS2/visuren/position-absolute-percentage-inherit-001.xht
+ Fail => Pass css/compositing/mix-blend-mode/mix-blend-mode-parent-element-overflow-scroll-blended-position-fixed.html
+ Fail => Pass css/css-align/abspos/align-self-with-flex-grid-parent.html
- Pass => Fail css/css-anchor-position/anchor-abspos-to-fixedpos-002.html
- Pass => Fail css/css-anchor-position/anchor-abspos-to-fixedpos-003.html
- Pass => Fail css/css-anchor-position/anchor-position-dynamic-005.html
- Pass => Fail css/css-anchor-position/anchor-scroll-fixedpos-003.html
! Fail => Timeout css/css-anchor-position/anchor-transition-focus.html
- Pass => Fail css/css-anchor-position/position-visibility-anchor-visible.html
- Pass => Fail css/css-anchor-position/position-visibility-anchors-visible-in-overflow.html
- Pass => Fail css/css-anchor-position/position-visibility-anchors-visible-position-fixed.html
- Pass => Fail css/css-anchor-position/position-visibility-anchors-visible.html
- Pass => Fail css/css-anchor-position/position-visibility-initial.html
! Fail => Timeout css/css-backgrounds/animations/background-position-interpolation.html
+ Fail => Pass css/css-backgrounds/background-origin-006.html
+ Fail => Pass css/css-backgrounds/background-rounded-image-clip-001.html
+ Fail => Pass css/css-backgrounds/background-size-percentage-root.html
+ Fail => Pass css/css-backgrounds/box-shadow/slice-inline-fragmentation-002.html
- Pass => Fail css/css-break/grid/grid-item-oof-012.html
+ Fail => Pass css/css-break/out-of-flow-in-multicolumn-091.html
+ Fail => Pass css/css-break/out-of-flow-in-multicolumn-092.html
+ Fail => Pass css/css-conditional/container-queries/no-layout-containment-abspos.html
+ Fail => Pass css/css-conditional/container-queries/no-layout-containment-fixedpos.html
- Pass => Fail css/css-contain/contain-layout-020.html
- Pass => Fail css/css-contain/contain-layout-021.html
- Pass => Fail css/css-contain/contain-layout-ignored-cases-ib-split-001.html
+ Fail => Pass css/css-contain/contain-paint-dynamic-001.html
- Pass => Fail css/css-contain/contain-paint-ignored-cases-ib-split-001.html
- Pass => Fail css/css-contain/content-visibility/content-visibility-092.html
- Pass => Fail css/css-contain/content-visibility/content-visibility-093.html
- Pass => Fail css/css-contain/content-visibility/content-visibility-095.html
- Pass => Fail css/css-contain/content-visibility/content-visibility-hidden-boundingbox-query.html
+ Fail => Pass css/css-flexbox/abspos/position-absolute-002.html
+ Fail => Pass css/css-flexbox/flexbox-paint-ordering-003.html
+ Fail => Pass css/css-flexbox/flexbox_margin-left-ex.html
- Pass => Fail css/css-flexbox/table-as-item-large-intrinsic-size.html
+ Fail => Pass css/css-grid/abspos/absolute-positioning-grid-container-containing-block-001.html
- Pass => Fail css/css-grid/abspos/grid-abspos-staticpos-align-self-safe-outer-cb-003.tentative.html
+ Fail => Pass css/css-grid/abspos/grid-positioned-item-dynamic-change-002.html
+ Fail => Pass css/css-grid/abspos/orthogonal-positioned-grid-descendants-016.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendant-containing-block-004.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendant-containing-block-006.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendant-containing-block-007.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendant-containing-block-008.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendant-containing-block-012.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendant-containing-block-014.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendant-containing-block-015.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendant-containing-block-016.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-002.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-004.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-006.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-007.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-008.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-009.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-011.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-012.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-013.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-014.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-015.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-016.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-descendants-017.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-items-019.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-items-024.html
+ Fail => Pass css/css-grid/abspos/positioned-grid-items-should-not-take-up-space-001.html
+ Fail => Pass css/css-grid/grid-items/grid-items-percentage-paddings-015.html
- Pass => Fail css/css-grid/grid-items/grid-items-relative-positioned-containing-block-003.html
+ Fail => Pass css/css-grid/grid-lanes/subgrid/grid-subgridded-to-grid-lanes/column-subgrid-abs-pos-001.html
+ Fail => Pass css/css-grid/parsing/grid-template-columns-computed-implicit-track.html
+ Fail => Pass css/css-grid/parsing/grid-template-rows-computed-implicit-track.html
+ Fail => Pass css/css-grid/subgrid/abs-pos-001.html
- Pass => Fail css/css-images/image-orientation/image-orientation-img-object-fit.html
- Pass => Fail css/css-inline/empty-span-scroll.html
- Pass => Fail css/css-masking/clip-path/clip-path-on-fixed-position-scroll.html
! Fail => Timeout css/css-multicol/animation/columns-interpolation.html
+ Fail => Pass css/css-multicol/multicol-contained-absolute.html
+ Fail => Pass css/css-multicol/multicol-oof-inline-cb-001.html
- Pass => Fail css/css-overflow/scroll-markers/scroll-target-group-012.html
+ Fail => Pass css/css-overflow/scrollable-overflow-fixed-positioned-initial-containing-block.html
+ Fail => Pass css/css-page/fixedpos-005-print.html
+ Fail => Pass css/css-page/fixedpos-007-print.html
+ Fail => Pass css/css-page/fixedpos-008-print.html
+ Fail => Pass css/css-position/absolute-pos-box-inside-fixed-pos-box-with-changing-height.html
+ Fail => Pass css/css-position/hypothetical-box-scroll-parent.html
+ Fail => Pass css/css-position/hypothetical-dynamic-change-003.html
- Pass => Fail css/css-position/nested-inline-abspos-child-with-siblings.html
- Pass => Fail css/css-position/nested-inline-abspos-child.html
+ Fail => Pass css/css-position/overlay/author-overlay-top-layer-removal.html
+ Fail => Pass css/css-position/position-absolute-center-003.html
+ Fail => Pass css/css-position/position-absolute-center-004.html
+ Fail => Pass css/css-position/position-absolute-dynamic-containing-block.html
+ Fail => Pass css/css-position/position-fixed-dynamic-transformed-sibling.html
+ Fail => Pass css/css-position/position-fixed-overflow-print.html
+ Fail => Pass css/css-position/position-fixed-scroll-nested-fixed.html
+ Fail => Pass css/css-position/position-static-001.html
+ Fail => Pass css/css-position/sticky/position-sticky-escape-scroller-001.html
+ Fail => Pass css/css-position/sticky/position-sticky-escape-scroller-003.html
- Pass => Fail css/css-position/sticky/position-sticky-escape-scroller-004.html
- Pass => Fail css/css-position/sticky/position-sticky-stacking-context-002.html
+ Fail => Pass css/css-position/sticky/position-sticky-stacking-context.html
- Pass => Fail css/css-pseudo/first-letter-width-2.html
! Fail => Timeout css/css-shapes/shape-outside/values/shape-outside-circle-004.html
! Fail => Timeout css/css-shapes/shape-outside/values/shape-outside-ellipse-004.html
! Timeout => Fail css/css-shapes/shape-outside/values/shape-outside-inset-001.html
! Fail => Timeout css/css-sizing/contain-intrinsic-size/animation/contain-intrinsic-size-interpolation.html
+ Fail => Pass css/css-tables/absolute-tables-010.tentative.html
! Fail => Timeout css/css-text-decor/animations/text-underline-offset-interpolation.html
+ Fail => Pass css/css-text-decor/text-shadow/text-shadow-emoji-transparent.html
! Fail => Timeout css/css-transforms/animation/perspective-interpolation.html
! Fail => Timeout css/css-transforms/animation/transform-interpolation-002.html
- Pass => Fail css/css-transforms/backface-visibility-hidden-animated-001.html
- Pass => Fail css/css-transforms/backface-visibility-hidden-animated-002.html
+ Fail => Pass css/css-transforms/perspective-containing-block-dynamic-1a.html
+ Fail => Pass css/css-transforms/preserve-3d-flat-grouping-properties-containing-block-inline.tentative.html
- Pass => Fail css/css-transforms/transform-containing-block-and-scrolling-area-for-fixed.html
+ Fail => Pass css/css-transforms/transform-containing-block-dynamic-1a.html
+ Fail => Pass css/css-transforms/ttwf-transform-translatex-001.html
+ Fail => Pass css/css-transforms/ttwf-transform-translatey-001.html
! Fail => Timeout css/css-values/calc-size/animation/interpolate-size-height-interpolation.html
! Fail => Timeout css/css-values/calc-size/animation/interpolate-size-max-height-interpolation.html
! Fail => Timeout css/css-view-transitions/parsing/pseudo-elements-invalid.html
+ Fail => Pass css/css-viewport/zoom/explicit-inherit/bottom.html
+ Fail => Pass css/css-viewport/zoom/explicit-inherit/left.html
+ Fail => Pass css/css-viewport/zoom/explicit-inherit/right.html
+ Fail => Pass css/css-viewport/zoom/explicit-inherit/top.html
+ Fail => Pass css/css-will-change/will-change-fixedpos-cb-003.html
+ Fail => Pass css/css-will-change/will-change-fixedpos-cb-006.html
+ Fail => Pass css/css-will-change/will-change-fixpos-cb-height-1.html
+ Fail => Pass css/css-will-change/will-change-fixpos-cb-position-1.html
+ Fail => Pass css/css-writing-modes/dynamic-offset-rtl-001.html
+ Fail => Pass css/css-writing-modes/dynamic-offset-rtl-002.html
+ Fail => Pass css/css-writing-modes/dynamic-offset-vrl-001.html
+ Fail => Pass css/css-writing-modes/dynamic-offset-vrl-rtl-001.html
+ Fail => Pass css/css-writing-modes/float-rgt-orthog-htb-in-vrl-003.xht
+ Fail => Pass css/cssom-view/CaretPosition-001.html
+ Fail => Pass css/cssom-view/getClientRects-inline.html
! Fail => Timeout css/filter-effects/animation/backdrop-filter-interpolation-001.html
- Pass => Fail css/filter-effects/backdrop-filter-clip-rect-zoom.html
- Pass => Fail css/filter-effects/backdrop-filter-plus-mask-large.html
+ Fail => Pass css/filter-effects/filter-cb-dynamic-1a.html
! Timeout => Fail css/motion/animation/offset-rotate-interpolation.html

Generated by the WPT workflow.

@staging-devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@staging-devin-ai-integration
staging-devin-ai-integration Bot force-pushed the devin/1787748926-taffy-oof-hoisting-latebound branch 3 times, most recently from 9c79ae6 to 4f6fbef Compare August 26, 2026 13:43
…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.
@staging-devin-ai-integration
staging-devin-ai-integration Bot force-pushed the devin/1787748926-taffy-oof-hoisting-latebound branch from 4f6fbef to 89c20f9 Compare August 29, 2026 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant