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

1 participant