From 8002efe78093d4c0852b9086ff9d9abb245158bd Mon Sep 17 00:00:00 2001 From: InvalidUsernameException Date: Thu, 10 Jul 2025 13:27:53 +0200 Subject: [PATCH] LibWeb: Don't distort replaced elements with natural size in flex layout When layouting a replaced element with natural width and height (e.g. a raster graphic), the replaced element would correctly end up with its natural size in the main-axis dimension. For the cross axis dimension however, the replaced element was stretched or squished to the flex containers inner cross size, which is wrong. Instead, we need to respect the replaced elements aspect ratio. Since the touched code does not have a direct correspondence to any spec text, I am not fully certain that the change is completely correct. However, tests agree with it, so the new code seems more correct than the old one at least. This fixes 50 WPT subtests in `css/css-flexbox`, most of which are already in-tree. I have also created a new test for a scenario that did not seem to be covered by WPT. --- .../LibWeb/Layout/FlexFormattingContext.cpp | 2 +- ...-intrinsic-aspect-ratio-and-max-height.txt | 4 +-- ...tainer-with-oversized-replaced-element.txt | 3 ++ .../flex-aspect-ratio-img-row-005.txt | 5 ++-- .../image-as-flexitem-size-001.txt | 22 +++++++------- .../image-as-flexitem-size-001v.txt | 22 +++++++------- .../image-as-flexitem-size-002.txt | 22 +++++++------- .../image-as-flexitem-size-002v.txt | 22 +++++++------- .../image-as-flexitem-size-007.txt | 12 ++++---- .../image-as-flexitem-size-007v.txt | 12 ++++---- ...ainer-with-oversized-replaced-element.html | 30 +++++++++++++++++++ 11 files changed, 94 insertions(+), 62 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/flex-container-with-oversized-replaced-element.txt create mode 100644 Tests/LibWeb/Text/input/flex-container-with-oversized-replaced-element.html diff --git a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 760a6a524ca..4629d4c9246 100644 --- a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -1137,7 +1137,7 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem& } if (item.box->has_preferred_aspect_ratio()) { - if (item.used_flex_basis_is_definite) { + if (item.used_flex_basis_is_definite || (item.box->has_natural_width() && item.box->has_natural_height())) { item.hypothetical_cross_size = calculate_cross_size_from_main_size_and_aspect_ratio(item.main_size.value(), item.box->preferred_aspect_ratio().value()); return; } diff --git a/Tests/LibWeb/Layout/expected/flex/flex-item-with-intrinsic-aspect-ratio-and-max-height.txt b/Tests/LibWeb/Layout/expected/flex/flex-item-with-intrinsic-aspect-ratio-and-max-height.txt index b55ef562afd..59d3e5cfa9d 100644 --- a/Tests/LibWeb/Layout/expected/flex/flex-item-with-intrinsic-aspect-ratio-and-max-height.txt +++ b/Tests/LibWeb/Layout/expected/flex/flex-item-with-intrinsic-aspect-ratio-and-max-height.txt @@ -1,14 +1,14 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer at (1,1) content-size 798x69.984375 [BFC] children: not-inline Box at (10,10) content-size 780x51.984375 flex-container(row) [FFC] children: not-inline - ImageBox at (11,10) content-size 66.65625x50 flex-item children: not-inline + ImageBox at (11,11) content-size 66.65625x49.984375 flex-item children: not-inline BlockContainer <(anonymous)> (not painted) [BFC] children: inline TextNode <#text> ViewportPaintable (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x71.984375] PaintableBox (Box) [9,9 782x53.984375] - ImagePaintable (ImageBox) [10,9 68.65625x52] + ImagePaintable (ImageBox) [10,10 68.65625x51.984375] SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto) SC for BlockContainer [1,1 798x69.984375] [children: 0] (z-index: auto) diff --git a/Tests/LibWeb/Text/expected/flex-container-with-oversized-replaced-element.txt b/Tests/LibWeb/Text/expected/flex-container-with-oversized-replaced-element.txt new file mode 100644 index 00000000000..f513c67b27c --- /dev/null +++ b/Tests/LibWeb/Text/expected/flex-container-with-oversized-replaced-element.txt @@ -0,0 +1,3 @@ +Natural height of image (400px) should be same as computed height (400px). +Natural width of image (200px) should be same as computed width (200px). +Computed height of image (400px) should be larger than computed height of container (200px). diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/flex-aspect-ratio-img-row-005.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/flex-aspect-ratio-img-row-005.txt index 54c4e3b69e0..a06fa57038e 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/flex-aspect-ratio-img-row-005.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/flex-aspect-ratio-img-row-005.txt @@ -2,9 +2,8 @@ Harness status: OK Found 4 tests -3 Pass -1 Fail +4 Pass Pass img 1 Pass img 2 Pass img 3 -Fail img 4 \ No newline at end of file +Pass img 4 \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-001.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-001.txt index 19f85f2623b..58de06ef22f 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-001.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-001.txt @@ -2,20 +2,20 @@ Harness status: OK Found 18 tests -5 Pass -13 Fail -Fail .flexbox > img 1 +14 Pass +4 Fail +Pass .flexbox > img 1 Pass .flexbox > img 2 Pass .flexbox > img 3 Pass .flexbox > img 4 -Fail .flexbox > img 5 -Fail .flexbox > img 6 -Fail .flexbox > img 7 -Fail .flexbox > img 8 -Fail .flexbox > img 9 -Fail .flexbox > img 10 -Fail .flexbox > img 11 -Fail .flexbox > img 12 +Pass .flexbox > img 5 +Pass .flexbox > img 6 +Pass .flexbox > img 7 +Pass .flexbox > img 8 +Pass .flexbox > img 9 +Pass .flexbox > img 10 +Pass .flexbox > img 11 +Pass .flexbox > img 12 Fail .flexbox > img 13 Fail .flexbox > img 14 Pass .flexbox > img 15 diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-001v.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-001v.txt index 19f85f2623b..58de06ef22f 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-001v.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-001v.txt @@ -2,20 +2,20 @@ Harness status: OK Found 18 tests -5 Pass -13 Fail -Fail .flexbox > img 1 +14 Pass +4 Fail +Pass .flexbox > img 1 Pass .flexbox > img 2 Pass .flexbox > img 3 Pass .flexbox > img 4 -Fail .flexbox > img 5 -Fail .flexbox > img 6 -Fail .flexbox > img 7 -Fail .flexbox > img 8 -Fail .flexbox > img 9 -Fail .flexbox > img 10 -Fail .flexbox > img 11 -Fail .flexbox > img 12 +Pass .flexbox > img 5 +Pass .flexbox > img 6 +Pass .flexbox > img 7 +Pass .flexbox > img 8 +Pass .flexbox > img 9 +Pass .flexbox > img 10 +Pass .flexbox > img 11 +Pass .flexbox > img 12 Fail .flexbox > img 13 Fail .flexbox > img 14 Pass .flexbox > img 15 diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-002.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-002.txt index c739e945e26..b6da3866cad 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-002.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-002.txt @@ -2,20 +2,20 @@ Harness status: OK Found 18 tests -5 Pass -13 Fail -Fail .flexbox > img 1 +14 Pass +4 Fail +Pass .flexbox > img 1 Pass .flexbox > img 2 Pass .flexbox > img 3 Pass .flexbox > img 4 -Fail .flexbox > img 5 -Fail .flexbox > img 6 -Fail .flexbox > img 7 -Fail .flexbox > img 8 -Fail .flexbox > img 9 -Fail .flexbox > img 10 -Fail .flexbox > img 11 -Fail .flexbox > img 12 +Pass .flexbox > img 5 +Pass .flexbox > img 6 +Pass .flexbox > img 7 +Pass .flexbox > img 8 +Pass .flexbox > img 9 +Pass .flexbox > img 10 +Pass .flexbox > img 11 +Pass .flexbox > img 12 Fail .flexbox > img 13 Fail .flexbox > img 14 Fail .flexbox > img 15 diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-002v.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-002v.txt index c739e945e26..b6da3866cad 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-002v.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-002v.txt @@ -2,20 +2,20 @@ Harness status: OK Found 18 tests -5 Pass -13 Fail -Fail .flexbox > img 1 +14 Pass +4 Fail +Pass .flexbox > img 1 Pass .flexbox > img 2 Pass .flexbox > img 3 Pass .flexbox > img 4 -Fail .flexbox > img 5 -Fail .flexbox > img 6 -Fail .flexbox > img 7 -Fail .flexbox > img 8 -Fail .flexbox > img 9 -Fail .flexbox > img 10 -Fail .flexbox > img 11 -Fail .flexbox > img 12 +Pass .flexbox > img 5 +Pass .flexbox > img 6 +Pass .flexbox > img 7 +Pass .flexbox > img 8 +Pass .flexbox > img 9 +Pass .flexbox > img 10 +Pass .flexbox > img 11 +Pass .flexbox > img 12 Fail .flexbox > img 13 Fail .flexbox > img 14 Fail .flexbox > img 15 diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-007.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-007.txt index 19f85f2623b..b9267f8b609 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-007.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-007.txt @@ -2,20 +2,20 @@ Harness status: OK Found 18 tests -5 Pass -13 Fail -Fail .flexbox > img 1 +9 Pass +9 Fail +Pass .flexbox > img 1 Pass .flexbox > img 2 Pass .flexbox > img 3 Pass .flexbox > img 4 -Fail .flexbox > img 5 +Pass .flexbox > img 5 Fail .flexbox > img 6 Fail .flexbox > img 7 Fail .flexbox > img 8 -Fail .flexbox > img 9 +Pass .flexbox > img 9 Fail .flexbox > img 10 Fail .flexbox > img 11 -Fail .flexbox > img 12 +Pass .flexbox > img 12 Fail .flexbox > img 13 Fail .flexbox > img 14 Pass .flexbox > img 15 diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-007v.txt b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-007v.txt index 19f85f2623b..b9267f8b609 100644 --- a/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-007v.txt +++ b/Tests/LibWeb/Text/expected/wpt-import/css/css-flexbox/image-as-flexitem-size-007v.txt @@ -2,20 +2,20 @@ Harness status: OK Found 18 tests -5 Pass -13 Fail -Fail .flexbox > img 1 +9 Pass +9 Fail +Pass .flexbox > img 1 Pass .flexbox > img 2 Pass .flexbox > img 3 Pass .flexbox > img 4 -Fail .flexbox > img 5 +Pass .flexbox > img 5 Fail .flexbox > img 6 Fail .flexbox > img 7 Fail .flexbox > img 8 -Fail .flexbox > img 9 +Pass .flexbox > img 9 Fail .flexbox > img 10 Fail .flexbox > img 11 -Fail .flexbox > img 12 +Pass .flexbox > img 12 Fail .flexbox > img 13 Fail .flexbox > img 14 Pass .flexbox > img 15 diff --git a/Tests/LibWeb/Text/input/flex-container-with-oversized-replaced-element.html b/Tests/LibWeb/Text/input/flex-container-with-oversized-replaced-element.html new file mode 100644 index 00000000000..c24651cef59 --- /dev/null +++ b/Tests/LibWeb/Text/input/flex-container-with-oversized-replaced-element.html @@ -0,0 +1,30 @@ + + + +
+ +
+