From 1583e6ce0763faaf73b5497f2c4eb6410d107674 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 25 Jan 2024 12:51:33 +0100 Subject: [PATCH] LibWeb: Clamp justification space between flex items to 0 Before this change, it was possible for flex lines with negative remaining space (due to overflowing items) to put a negative amount of space between items for some values of `justify-content`. This makes https://polar.sh/SerenityOS look much better :^) --- ...-with-negative-remaining-space-on-line.txt | 19 ++++++++++++ ...with-negative-remaining-space-on-line.html | 29 +++++++++++++++++++ .../LibWeb/Layout/FlexFormattingContext.cpp | 6 ++-- 3 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 Tests/LibWeb/Layout/expected/flex/space-between-with-negative-remaining-space-on-line.txt create mode 100644 Tests/LibWeb/Layout/input/flex/space-between-with-negative-remaining-space-on-line.html diff --git a/Tests/LibWeb/Layout/expected/flex/space-between-with-negative-remaining-space-on-line.txt b/Tests/LibWeb/Layout/expected/flex/space-between-with-negative-remaining-space-on-line.txt new file mode 100644 index 0000000000..4e1e3dceed --- /dev/null +++ b/Tests/LibWeb/Layout/expected/flex/space-between-with-negative-remaining-space-on-line.txt @@ -0,0 +1,19 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x116 [BFC] children: not-inline + Box at (8,8) content-size 400x100 flex-container(row) [FFC] children: not-inline + Box at (8,8) content-size 200x100 flex-container(column) flex-item [FFC] children: not-inline + BlockContainer at (8,8) content-size 200x200 flex-item [BFC] children: not-inline + BlockContainer at (8,8) content-size 200x200 children: not-inline + BlockContainer at (8,208) content-size 200x17 flex-item [BFC] children: inline + frag 0 from TextNode start: 0, length: 3, rect: [8,208 26.953125x17] baseline: 13.296875 + "whf" + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x116] overflow: [0,0 800x225] + PaintableBox (Box) [8,8 400x100] overflow: [8,8 400x217] + PaintableBox (Box
.outer) [8,8 200x100] overflow: [8,8 200x217] + PaintableWithLines (BlockContainer
.upper) [8,8 200x200] + PaintableWithLines (BlockContainer
.spacer) [8,8 200x200] + PaintableWithLines (BlockContainer
.lower) [8,208 200x17] + TextPaintable (TextNode<#text>) diff --git a/Tests/LibWeb/Layout/input/flex/space-between-with-negative-remaining-space-on-line.html b/Tests/LibWeb/Layout/input/flex/space-between-with-negative-remaining-space-on-line.html new file mode 100644 index 0000000000..715368fc06 --- /dev/null +++ b/Tests/LibWeb/Layout/input/flex/space-between-with-negative-remaining-space-on-line.html @@ -0,0 +1,29 @@ +
whf diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 2746a5660b..f5e9e456c0 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -1230,11 +1230,11 @@ void FlexFormattingContext::distribute_any_remaining_free_space() initial_offset = 0; } if (flex_line.remaining_free_space.has_value() && number_of_items > 1) - space_between_items = flex_line.remaining_free_space.value() / (number_of_items - 1); + space_between_items = max(CSSPixels(0), flex_line.remaining_free_space.value() / (number_of_items - 1)); break; case CSS::JustifyContent::SpaceAround: if (flex_line.remaining_free_space.has_value()) - space_between_items = flex_line.remaining_free_space.value() / number_of_items; + space_between_items = max(CSSPixels(0), flex_line.remaining_free_space.value() / number_of_items); if (is_direction_reverse()) { initial_offset = inner_main_size(m_flex_container_state) - space_between_items / 2; } else { @@ -1243,7 +1243,7 @@ void FlexFormattingContext::distribute_any_remaining_free_space() break; case CSS::JustifyContent::SpaceEvenly: if (flex_line.remaining_free_space.has_value()) - space_between_items = flex_line.remaining_free_space.value() / (number_of_items + 1); + space_between_items = max(CSSPixels(0), flex_line.remaining_free_space.value() / (number_of_items + 1)); if (is_direction_reverse()) { initial_offset = inner_main_size(m_flex_container_state) - space_between_items; } else {