Skip to content

Fix automatic minimum size and aspect-ratio sizing of replaced flex items - #526

Closed
nicoburns wants to merge 2 commits into
mainfrom
devin/1784873193-flexbox-min-size-aspect-ratio
Closed

Fix automatic minimum size and aspect-ratio sizing of replaced flex items#526
nicoburns wants to merge 2 commits into
mainfrom
devin/1784873193-flexbox-min-size-aspect-ratio

Conversation

@nicoburns

@nicoburns nicoburns commented Jul 24, 2026

Copy link
Copy Markdown
Member

Summary

Fixes a group of failing css-flexbox WPT tests around min-width/height: auto (automatic minimum size, css-flexbox-1 §4.5) and aspect-ratio/replaced flex items. Full just wpt css/css-flexbox results: 654 → 699 whole tests passed, 1714 → 1765 subtests passed (no regressions; a companion Taffy fix adds 6 more, see below).

Root causes and fixes:

  • replaced_measure_function re-clamped/overrode sizes already resolved by the parent layout algorithm. It now receives sizing_mode and requested_axis from LayoutInput:
    • Known dimensions are returned directly (only the unspecified axis, derived via the aspect ratio, is still clamped by min/max). Previously a flex item that Taffy had grown to e.g. 100px came back as its 10px natural size.
    • In SizingMode::ContentSize, preferred/min size styles in the measured axis are ignored (the parent algorithm applies them itself), while opposite-axis constraints are kept so they transfer through the aspect ratio (transferred size suggestion).
  • SVG intrinsic sizing. SvgImageData now records viewbox_aspect_ratio alongside the absolute intrinsic_width/intrinsic_height, and intrinsic_size() implements CSS replaced-element sizing: declared absolute dimensions win; a missing dimension is computed from the viewBox ratio; with no dimensions at all, the CSS default object size (300x150, contained by the intrinsic ratio) applies. Previously usvg::Tree::size() was used directly, which resolves viewBox-only SVGs to the viewBox dimensions. parse_svg_image also re-parses with the CSS-computed missing dimension injected so the painted canvas matches layout.
  • Canvas sizing. <canvas> elements now get their intrinsic size from width/height attributes (default 300x150) instead of 0x0, and canvas was missing from the inline-box tag list in construct.rs, so inline canvases were dropped from layout entirely.
  • WPT runner: implemented data-expected-client-width/height assertions (border-box size minus borders).

Companion Taffy PR (transferred min/max sizes, cross-size clamping in flex base size calculation) fixes 6 further tests in this group: flex-minimum-width-flex-items-012, flexbox-min-width-auto-002c, flexbox-min-height-auto-002c, flex-minimum-height-flex-items-021, flex-aspect-ratio-img-column-005, aspect-ratio-transferred-max-size.

Tests fixed (requested group): flex-minimum-width-flex-items-004..013, flexbox-min-width-auto-002a/b/c, flex-aspect-ratio-img-row-001/002/003/007/008/009/010/011/013/015/017, flex-aspect-ratio-img-column-013, aspect-ratio-intrinsic-size-001, flexitem-percentage-height-img-001, plus 3 of 4 subtests of flex-aspect-ratio-img-row-005.

Not fixed (with reasons):

  • flex-minimum-height-flex-items-009 — requires dynamic style mutation via script + relayout (runner limitation).
  • flexitem-stretch-image — needs data-expected-display runner support and hypothetical-cross-size-from-flexed-main-size behaviour.
  • flex-minimum-size-001 (5/6), flex-minimum-size-002, flex-aspect-ratio-cross-size-002 — percentage min-size / nested percentage cross-size resolution issues out of scope for this group.
  • flex-aspect-ratio-img-row-005 (3/4) — remaining subtest needs content-box-aware aspect-ratio transfer in Taffy (Taffy currently applies aspect ratios to border-box sizes).

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


Devin Review

Status Commit
⚪ Not started

Run Devin Review

Open in Devin Review (Staging)

WPT results

96 newly passing, 10 newly failing (net +86).

Full diff (106 changed tests)
+ Fail => Pass css/css-backgrounds/background-size/vector/tall--contain--height.html
+ Fail => Pass css/css-backgrounds/background-size/vector/tall--contain--width.html
+ Fail => Pass css/css-backgrounds/background-size/vector/wide--contain--height.html
+ Fail => Pass css/css-backgrounds/background-size/vector/wide--contain--width.html
+ Fail => Pass css/css-contain/content-visibility/content-visibility-canvas.html
+ Fail => Pass css/css-flexbox/aspect-ratio-intrinsic-size-001.html
- Pass => Fail css/css-flexbox/aspect-ratio-intrinsic-size-007.html
+ Fail => Pass css/css-flexbox/canvas-contain-size.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-001.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-002.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-003.html
- Pass => Fail css/css-flexbox/flex-aspect-ratio-img-column-005.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-012.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-013.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-014.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-015.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-017.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-column-018.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-001.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-002.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-003.html
- Pass => Fail css/css-flexbox/flex-aspect-ratio-img-row-005.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-007.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-008.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-009.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-010.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-011.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-013.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-015.html
+ Fail => Pass css/css-flexbox/flex-aspect-ratio-img-row-017.html
+ Fail => Pass css/css-flexbox/flex-item-percentage-height-img-001.html
+ Fail => Pass css/css-flexbox/flex-minimum-height-flex-items-004.xht
+ Fail => Pass css/css-flexbox/flex-minimum-height-flex-items-005.xht
+ Fail => Pass css/css-flexbox/flex-minimum-height-flex-items-006.xht
+ Fail => Pass css/css-flexbox/flex-minimum-height-flex-items-007.xht
+ Fail => Pass css/css-flexbox/flex-minimum-height-flex-items-008.xht
+ Fail => Pass css/css-flexbox/flex-minimum-height-flex-items-020.html
+ Fail => Pass css/css-flexbox/flex-minimum-height-flex-items-022.html
+ Fail => Pass css/css-flexbox/flex-minimum-height-flex-items-023.html
+ Fail => Pass css/css-flexbox/flex-minimum-size-003.html
+ Fail => Pass css/css-flexbox/flex-minimum-width-flex-items-004.xht
+ Fail => Pass css/css-flexbox/flex-minimum-width-flex-items-005.xht
+ Fail => Pass css/css-flexbox/flex-minimum-width-flex-items-006.xht
+ Fail => Pass css/css-flexbox/flex-minimum-width-flex-items-007.xht
+ Fail => Pass css/css-flexbox/flex-minimum-width-flex-items-008.xht
+ Fail => Pass css/css-flexbox/flex-minimum-width-flex-items-009.html
+ Fail => Pass css/css-flexbox/flex-minimum-width-flex-items-010.html
+ Fail => Pass css/css-flexbox/flex-minimum-width-flex-items-011.html
+ Fail => Pass css/css-flexbox/flex-minimum-width-flex-items-013.html
+ Fail => Pass css/css-flexbox/flex-svg-no-intrinsic-column-001.html
+ Fail => Pass css/css-flexbox/flexbox-basic-canvas-horiz-001.xhtml
+ Fail => Pass css/css-flexbox/flexbox-basic-canvas-horiz-001v.xhtml
+ Fail => Pass css/css-flexbox/flexbox-flex-basis-content-003a.html
+ Fail => Pass css/css-flexbox/flexbox-flex-basis-content-003b.html
+ Fail => Pass css/css-flexbox/flexbox-min-height-auto-002a.html
+ Fail => Pass css/css-flexbox/flexbox-min-height-auto-002b.html
+ Fail => Pass css/css-flexbox/flexbox-min-width-auto-002a.html
+ Fail => Pass css/css-flexbox/flexbox-min-width-auto-002b.html
- Pass => Fail css/css-flexbox/image-as-flexitem-size-003.html
- Pass => Fail css/css-flexbox/image-as-flexitem-size-003v.html
- Pass => Fail css/css-flexbox/image-as-flexitem-size-004.html
- Pass => Fail css/css-flexbox/image-as-flexitem-size-004v.html
+ Fail => Pass css/css-flexbox/image-items-flake-001.html
+ Fail => Pass css/css-flexbox/relayout-intrinsic-block-size.html
- Pass => Fail css/css-flexbox/svg-root-as-flex-item-002.html
- Pass => Fail css/css-grid/grid-item-percentage-quirk-001.html
+ Fail => Pass css/css-grid/grid-items/grid-item-inline-contribution-001.html
+ Fail => Pass css/css-grid/grid-items/grid-item-inline-contribution-002.html
+ Fail => Pass css/css-grid/grid-items/grid-item-inline-contribution-003.html
+ Fail => Pass css/css-grid/grid-items/grid-item-inline-contribution-004.html
+ Fail => Pass css/css-grid/grid-items/grid-item-inline-contribution-005.html
+ Fail => Pass css/css-grid/grid-items/replaced-element-011.html
+ Fail => Pass css/css-grid/grid-items/replaced-element-012.html
+ Fail => Pass css/css-grid/grid-items/replaced-element-013.html
+ Fail => Pass css/css-grid/layout-algorithm/grid-float-intrinsic-width-percent-height-aspect-ratio-001.html
+ Fail => Pass css/css-grid/layout-algorithm/grid-inline-grid-intrinsic-width-percent-height-aspect-ratio-001.html
+ Fail => Pass css/css-grid/layout-algorithm/grid-track-ignores-max-size-002.html
+ Fail => Pass css/css-images/object-view-box-fit-contain-canvas.html
+ Fail => Pass css/css-images/object-view-box-fit-none-canvas.html
- Pass => Fail css/css-images/object-view-box-writing-mode-canvas.html
+ Fail => Pass css/css-paint-api/background-image-alpha.https.html
+ Fail => Pass css/css-paint-api/dynamic-import.https.html
+ Fail => Pass css/css-paint-api/paint-arguments.https.html
+ Fail => Pass css/css-paint-api/paint-function-arguments-var.https.html
+ Fail => Pass css/css-paint-api/paint-function-arguments.https.html
+ Fail => Pass css/css-paint-api/paint2d-rects.https.html
+ Fail => Pass css/css-paint-api/paint2d-roundRect.https.html
+ Fail => Pass css/css-paint-api/top-level-await.https.html
+ Fail => Pass css/css-position/position-absolute-replaced-intrinsic-size.tentative.html
+ Fail => Pass css/css-rhythm/replaced-elements/block-level-canvas-margins-affected-by-block-step-size.html
+ Fail => Pass css/css-sizing/aspect-ratio/replaced-element-039.html
+ Fail => Pass css/css-sizing/aspect-ratio/replaced-element-040.html
+ Fail => Pass css/css-sizing/intrinsic-percent-replaced-005.html
+ Fail => Pass css/css-sizing/intrinsic-percent-replaced-007.html
+ Fail => Pass css/css-sizing/intrinsic-percent-replaced-008.html
+ Fail => Pass css/css-sizing/intrinsic-percent-replaced-019.html
+ Fail => Pass css/css-sizing/intrinsic-percent-replaced-020.html
+ Fail => Pass css/css-sizing/intrinsic-percent-replaced-025.html
+ Fail => Pass css/css-sizing/intrinsic-percent-replaced-027.html
+ Fail => Pass css/css-sizing/intrinsic-percent-replaced-029.tentative.html
+ Fail => Pass css/css-sizing/intrinsic-percent-replaced-031.html
+ Fail => Pass css/css-sizing/intrinsic-percent-replaced-032.html
+ Fail => Pass css/css-sizing/intrinsic-percent-replaced-dynamic-005.html
+ Fail => Pass css/css-sizing/replaced-max-size-saturation.html
+ Fail => Pass css/css-tables/percent-height-replaced-in-percent-cell-002.html
+ Fail => Pass css/css-writing-modes/abs-pos-with-replaced-child.html

Generated by the WPT workflow.

@nicoburns nicoburns self-assigned this Jul 24, 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

@devin-ai-integration
devin-ai-integration Bot force-pushed the devin/1784873193-flexbox-min-size-aspect-ratio branch from 5a6ef1b to cdbf229 Compare July 24, 2026 18:30
@nicoburns
nicoburns marked this pull request as ready for review July 25, 2026 03:23
@devin-ai-integration
devin-ai-integration Bot force-pushed the devin/1784873193-flexbox-min-size-aspect-ratio branch from cdbf229 to 73efd3b Compare July 25, 2026 03:25
@devin-ai-integration
devin-ai-integration Bot force-pushed the devin/1784873193-flexbox-min-size-aspect-ratio branch from 73efd3b to 6ae77d2 Compare August 4, 2026 12:26
@devin-ai-integration

Copy link
Copy Markdown
Contributor

Split into focused PRs: #605 (replaced flex measurement), #606 (SVG intrinsic sizing), and #607 (canvas intrinsic/inline sizing).

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