Skip to content

Fix floats × inline content / line box WPT failures - #630

Draft
nicoburns wants to merge 4 commits into
devin/1786122908-taffy-git-depfrom
devin/1786137317-floats-inline-line-boxes
Draft

Fix floats × inline content / line box WPT failures#630
nicoburns wants to merge 4 commits into
devin/1786122908-taffy-git-depfrom
devin/1786137317-floats-inline-line-boxes

Conversation

@nicoburns

Copy link
Copy Markdown
Member

Summary

Fixes WPT failures in the "floats × inline content / line boxes" group, on top of #625. css/CSS2/floats + css/CSS2/floats-clear: 195 → 206 passing of 325 run (0 crashes), no regressions. (Locally-measured baseline for #625 was 195/130; the reported 192/133 could not be reproduced.)

Newly passing:

css/CSS2/floats/float-in-inline-001.html
css/CSS2/floats/float-in-inline-002.html
css/CSS2/floats/float-nowrap-4.html
css/CSS2/floats/floats-placement-vertical-001b.xht
css/CSS2/floats/floats-placement-vertical-001c.xht
css/CSS2/floats/floats-wrap-bfc-with-margin-007.tentative.html
css/CSS2/floats/zero-width-floats.html
css/CSS2/floats-clear/floats-149.xht
css/CSS2/floats-clear/margin-collapse-033.xht
css/CSS2/floats-clear/margin-collapse-034.xht
css/CSS2/floats-clear/margin-collapse-035.xht

(floats-006.xht, float-nowrap-3.html, float-nowrap-9.html were fixed as regressions of intermediate states and stay passing.)

Blitz changes

  1. Floats inside inline content stay in the IFC (float-in-inline-001/002): collect_complex_layout_children treated a floated child as block-level (its blockified display interrupted the inline formatting context, splitting it into anonymous blocks). Floated children are now classified as inline-level and become InlineBoxKind::CustomOutOfFlow inline boxes handled by the float machinery; Node::is_or_contains_block likewise no longer counts floated (or absolutely positioned) descendants as in-flow blocks.

  2. Text index / whitespace handling around out-of-flow inline boxes (floats-149, floats-006): Parley doesn't commit pending text when an out-of-flow inline box is pushed, so the box's text index ignored preceding uncommitted text. push_inline_box_with_index_fixup commits pending text via an empty style-modification span — but only when it contains non-whitespace (whitespace-only text must stay uncommitted so it collapses with surrounding text; committing it created a phantom root-styled run whose line-height misplaced later floats in floats-006). Committing sets Parley's "span first" flag which swallows a following collapsible space, so that space is re-inserted explicitly when needed.

  3. Speculative retry when Parley rewinds past a placed float (float-nowrap-3/4/9): with white-space: nowrap, Parley can rewind content that precedes an already-placed float onto a later line, re-encountering the float. Line breaking now runs in a retry loop (max 4 attempts):

    • a re-encountered float is not placed twice; if its line moved down, a retry is requested with the higher min-y;
    • after each pass, floats placed above a line box containing content that precedes them (CSS2 §9.5.1 rule 6) also force a retry;
    • each retry restores taffy float state via the new BlockContext::snapshot_float_state/restore_float_state API, so discarded attempts leave no phantom floats.

Taffy pin

Bumps the taffy pin to DioxusLabs/taffy#1070 (zero-width float vertical participation, real-float-edge tracking for BFC slots, and the float state snapshot/restore API). Once that merges, the pin can move back to main.

Remaining failures in this group

block-in-inline-become-float.html, float-nowrap-hyphen-rewind-1.html, float-no-content-beside-001.html, floats-line-wrap-shifted-001.html, intrinsic-size-float-and-line.html, zero-space-between-floats-003.html, floats-029/030/031/124/132.xht (line boxes shortening beside floats mid-paragraph — needs per-line width recomputation that accounts for line height before the line is broken). float-nowrap-5/6, floats-036, floats-114 are assigned to a separate session.

cargo fmt and cargo clippy --workspace are clean.

Link to Devin session: https://app.devin.ai/sessions/ca393611e919410aaa93e816fdf90a54
Requested by: @nicoburns

- Classify floated children of inline content as inline-level custom
  out-of-flow inline boxes rather than blocks that interrupt the IFC.
- Exclude floated descendants from Node::is_or_contains_block.
- Commit pending non-whitespace text before out-of-flow inline boxes so
  Parley assigns them a correct text index, restoring a swallowed
  collapsible space where needed; whitespace-only pending text is left
  uncommitted so it still collapses with surrounding text.
- Retry inline layout when Parley rewinds content past an already-placed
  float (or a float ends up above a line containing earlier content),
  restoring taffy float state via the new snapshot/restore API and
  re-placing floats with a corrected minimum y.
- Bump taffy pin to include zero-width float / BFC slot fixes and the
  float state snapshot API.
@nicoburns nicoburns self-assigned this Aug 7, 2026
@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/1786122908-taffy-git-dep branch from 252a5e8 to c24cb96 Compare August 7, 2026 23:18
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