From 89036dd70c30a52340b9fbdc8cada697cae30451 Mon Sep 17 00:00:00 2001 From: Michael Manganiello Date: Sun, 20 Jul 2025 00:11:41 -0300 Subject: [PATCH] LibWeb: Fix size computation for elements with max-width and max-height The specification [1] indicates that the tentative used width and height should be computed first, and if they exceed the `max-width` or `max-height`, the rules should be applied again using the computed values of `max-width` and `max-height`. The only required change to follow the spec is to remove the early `return` statements, in both `compute_width_for_replaced_element` and `compute_height_for_replaced_element`. Fixes #5100. [1] https://www.w3.org/TR/CSS22/visudet.html#min-max-widths --- Libraries/LibWeb/Layout/FormattingContext.cpp | 4 +--- .../image-with-max-width-and-max-height.txt | 14 ++++++++++++++ .../input/image-with-max-width-and-max-height.html | 8 ++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/image-with-max-width-and-max-height.txt create mode 100644 Tests/LibWeb/Layout/input/image-with-max-width-and-max-height.html diff --git a/Libraries/LibWeb/Layout/FormattingContext.cpp b/Libraries/LibWeb/Layout/FormattingContext.cpp index 085eb785d5e..a10e67e54fd 100644 --- a/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -583,10 +583,9 @@ CSSPixels FormattingContext::compute_width_for_replaced_element(Box const& box, CSSPixels w = used_width; CSSPixels h = tentative_height_for_replaced_element(box, computed_height, available_space); used_width = solve_replaced_size_constraint(w, h, box, available_space).width(); - return used_width; } - // 2. The tentative used width is greater than 'max-width', the rules above are applied again, + // 2. If the tentative used width is greater than 'max-width', the rules above are applied again, // but this time using the computed value of 'max-width' as the computed value for 'width'. if (!should_treat_max_width_as_none(box, available_space.width)) { auto const& computed_max_width = box.computed_values().max_width(); @@ -661,7 +660,6 @@ CSSPixels FormattingContext::compute_height_for_replaced_element(Box const& box, CSSPixels w = tentative_width_for_replaced_element(box, computed_width, available_space); CSSPixels h = used_height; used_height = solve_replaced_size_constraint(w, h, box, available_space).height(); - return used_height; } // 2. If this tentative height is greater than 'max-height', the rules above are applied again, diff --git a/Tests/LibWeb/Layout/expected/image-with-max-width-and-max-height.txt b/Tests/LibWeb/Layout/expected/image-with-max-width-and-max-height.txt new file mode 100644 index 00000000000..7d34ba58474 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/image-with-max-width-and-max-height.txt @@ -0,0 +1,14 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (1,1) content-size 798x70 [BFC] children: not-inline + BlockContainer at (10,10) content-size 780x52 children: inline + frag 0 from ImageBox start: 0, length: 0, rect: [11,11 66.65625x50] baseline: 52 + ImageBox at (11,11) content-size 66.65625x50 children: not-inline + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x72] + PaintableWithLines (BlockContainer) [9,9 782x54] + ImagePaintable (ImageBox) [10,10 68.65625x52] + +SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto) + SC for BlockContainer [1,1 798x70] [children: 0] (z-index: auto) diff --git a/Tests/LibWeb/Layout/input/image-with-max-width-and-max-height.html b/Tests/LibWeb/Layout/input/image-with-max-width-and-max-height.html new file mode 100644 index 00000000000..35cc9c52e2e --- /dev/null +++ b/Tests/LibWeb/Layout/input/image-with-max-width-and-max-height.html @@ -0,0 +1,8 @@ +