Skip to content

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

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

Integrate Taffy out-of-flow hoisting support#805
nicoburns wants to merge 13 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 = "76a28695" (stack top, includes the late-bound static-position representation, the CoreStyle::is_containing_block claim policy, 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.
  • Containing-block policy (stylo_taffy): TaffyStyloStyle implements CoreStyle::is_containing_block, returning ContainingBlockClaims via the new stylo_taffy::convert::containing_block_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. The predicates moved from Node into stylo_taffy::convert (establishes_fixed_containing_block/establishes_absolute_containing_block) since they are purely style-derived; the damage pass reuses the same claims via Node::containing_block_claims().for_position(..).
  • 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.

Requested by: @nicoburns

WPT results

Subtests: 1971 newly passing, 44 newly failing (net +1927). Timeouts: +1.

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

Generated by the WPT workflow.

Link to Devin session: https://dioxus.staging.devinenterprise.com/sessions/f415f9517ff44a2c84e7a03f9de5148a
Open in Devin Desktop: https://dioxus.staging.devinenterprise.com/desktop/session/f415f9517ff44a2c84e7a03f9de5148a?variant=devin-insiders

@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
@staging-devin-ai-integration
staging-devin-ai-integration Bot force-pushed the devin/1787748926-taffy-oof-hoisting-latebound branch 2 times, most recently from 89c20f9 to 0b9c934 Compare September 2, 2026 16:26
…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 69eb1e0 to 1aff5fc Compare September 2, 2026 17:03
Taffy's claim policy moved from a LayoutContainingBlock::oof_claims tree
hook to CoreStyle::is_containing_block (DioxusLabs/taffy#1170/#1172), so
that the grid algorithm's static-position emission and the positioning
pass share one source of truth. Implement it on TaffyStyloStyle, moving
the style-only fixed/absolute containing-block predicates into
stylo_taffy::convert, and reuse the same claims in the damage pass.

Bumps taffy to the rewritten stack top (5e71ce15).
… block

Hoisted (absolute/fixed) children were recursed into from their layout
parent (discarding the result) and then again from the containing block's
hoisted list, so nested positioned boxes cost 2^depth visits when damaged.
Skip them in the layout-children and pseudo-element loops, mirroring
Taffy's round_layout_inner, and share the predicate via Node::is_hoisted.
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