From 8d02f28cc2eb7410ad7a0f0a1c5afb84dbc9950b Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 23 Jul 2025 18:08:31 +0200 Subject: [PATCH] LibWeb: Don't treat non-replaced sizes as 0 for min-content contrib This behavior is part of the cyclic percentage contribution logic from CSS-SIZING-3 which explicitly only applies to non-replaced boxes. This fixes an issue on Discord where buttons in the settings UI were cropped to a narrower width than intended. Fixes #3572 --- .../LibWeb/Layout/FlexFormattingContext.cpp | 6 +++-- Libraries/LibWeb/Layout/FormattingContext.cpp | 7 +++++ ...uto-in-non-replaced-min-content-sizing.txt | 19 +++++++++++++ ...flex-container-with-definite-max-width.txt | 27 +++++++++++++++++++ ...width-contribution-to-min-content-size.txt | 18 +++++++++++++ ...to-in-non-replaced-min-content-sizing.html | 12 +++++++++ ...lex-container-with-definite-max-width.html | 15 +++++++++++ ...idth-contribution-to-min-content-size.html | 15 +++++++++++ 8 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/block-and-inline/treat-percentage-width-as-auto-in-non-replaced-min-content-sizing.txt create mode 100644 Tests/LibWeb/Layout/expected/flex/flex-item-with-percentage-width-in-flex-container-with-definite-max-width.txt create mode 100644 Tests/LibWeb/Layout/expected/flex/percent-width-contribution-to-min-content-size.txt create mode 100644 Tests/LibWeb/Layout/input/block-and-inline/treat-percentage-width-as-auto-in-non-replaced-min-content-sizing.html create mode 100644 Tests/LibWeb/Layout/input/flex/flex-item-with-percentage-width-in-flex-container-with-definite-max-width.html create mode 100644 Tests/LibWeb/Layout/input/flex/percent-width-contribution-to-min-content-size.html diff --git a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 4629d4c9246..fe342a9a567 100644 --- a/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -632,8 +632,10 @@ void FlexFormattingContext::determine_flex_base_size(FlexItem& item) } // AD-HOC: If we're sizing the flex container under a min-content constraint in the main axis, - // flex items resolve percentages in the main axis to 0. - if (m_available_space_for_items->main.is_min_content() + // non-replaced flex items resolve percentages in the main axis to 0. + // https://drafts.csswg.org/css-sizing-3/#cyclic-percentage-contribution + if (item.box->is_replaced_box() + && m_available_space_for_items->main.is_min_content() && computed_main_size(item.box).contains_percentage()) { return CSSPixels(0); } diff --git a/Libraries/LibWeb/Layout/FormattingContext.cpp b/Libraries/LibWeb/Layout/FormattingContext.cpp index a10e67e54fd..221102d1fba 100644 --- a/Libraries/LibWeb/Layout/FormattingContext.cpp +++ b/Libraries/LibWeb/Layout/FormattingContext.cpp @@ -1695,7 +1695,11 @@ bool FormattingContext::should_treat_width_as_auto(Box const& box, AvailableSpac auto const& computed_width = box.computed_values().width(); if (computed_width.is_auto()) return true; + + // https://drafts.csswg.org/css-sizing-3/#cyclic-percentage-contribution if (computed_width.contains_percentage()) { + if (!box.is_replaced_box() && available_space.width.is_min_content()) + return true; if (available_space.width.is_max_content()) return true; if (available_space.width.is_indefinite()) @@ -1724,7 +1728,10 @@ bool FormattingContext::should_treat_height_as_auto(Box const& box, AvailableSpa return true; } + // https://drafts.csswg.org/css-sizing-3/#cyclic-percentage-contribution if (computed_height.contains_percentage()) { + if (!box.is_replaced_box() && available_space.height.is_min_content()) + return true; if (available_space.height.is_max_content()) return true; if (available_space.height.is_indefinite()) diff --git a/Tests/LibWeb/Layout/expected/block-and-inline/treat-percentage-width-as-auto-in-non-replaced-min-content-sizing.txt b/Tests/LibWeb/Layout/expected/block-and-inline/treat-percentage-width-as-auto-in-non-replaced-min-content-sizing.txt new file mode 100644 index 00000000000..976fd8653a4 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/block-and-inline/treat-percentage-width-as-auto-in-non-replaced-min-content-sizing.txt @@ -0,0 +1,19 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x66 [BFC] children: inline + frag 0 from BlockContainer start: 0, length: 0, rect: [8,8 38.1875x50] baseline: 21.796875 + BlockContainer at (8,8) content-size 38.1875x50 inline-block [BFC] children: not-inline + BlockContainer
at (8,8) content-size 38.1875x20 children: inline + frag 0 from TextNode start: 0, length: 4, rect: [8,8 31.140625x18] baseline: 13.796875 + "Edit" + frag 1 from TextNode start: 5, length: 4, rect: [8,26 38.1875x18] baseline: 13.796875 + "User" + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x66] + PaintableWithLines (BlockContainer) [8,8 38.1875x50] + PaintableWithLines (BlockContainer
) [8,8 38.1875x20] overflow: [8,8 38.1875x36] + TextPaintable (TextNode<#text>) + +SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto) + SC for BlockContainer [0,0 800x66] [children: 0] (z-index: auto) diff --git a/Tests/LibWeb/Layout/expected/flex/flex-item-with-percentage-width-in-flex-container-with-definite-max-width.txt b/Tests/LibWeb/Layout/expected/flex/flex-item-with-percentage-width-in-flex-container-with-definite-max-width.txt new file mode 100644 index 00000000000..63c60bd16ec --- /dev/null +++ b/Tests/LibWeb/Layout/expected/flex/flex-item-with-percentage-width-in-flex-container-with-definite-max-width.txt @@ -0,0 +1,27 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x38 [BFC] children: not-inline + Box at (8,8) content-size 50x22 flex-container(row) [FFC] children: not-inline + BlockContainer
at (8,8) content-size 285.546875x22 flex-item [BFC] children: inline + frag 0 from BlockContainer start: 0, length: 0, rect: [13,10 275.546875x18] baseline: 15.796875 + TextNode <#text> + BlockContainer +
diff --git a/Tests/LibWeb/Layout/input/flex/percent-width-contribution-to-min-content-size.html b/Tests/LibWeb/Layout/input/flex/percent-width-contribution-to-min-content-size.html new file mode 100644 index 00000000000..5d3f5624232 --- /dev/null +++ b/Tests/LibWeb/Layout/input/flex/percent-width-contribution-to-min-content-size.html @@ -0,0 +1,15 @@ +
Edit User Profile \ No newline at end of file