diff --git a/Tests/LibWeb/Layout/expected/flex-margin-auto-justify-content.txt b/Tests/LibWeb/Layout/expected/flex-margin-auto-justify-content.txt new file mode 100644 index 0000000000..f1d4d357c4 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/flex-margin-auto-justify-content.txt @@ -0,0 +1,21 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x70 children: not-inline + BlockContainer at (8,8) content-size 784x54 children: not-inline + Box at (9,9) content-size 600x52 flex-container(row) children: not-inline + BlockContainer at (20,10) content-size 150x50 flex-item children: inline + line 0 width: 86.359375, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 11, rect: [20,10 86.359375x17.46875] + "left margin" + TextNode <#text> + BlockContainer at (172,10) content-size 150x50 flex-item children: inline + line 0 width: 141.28125, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 18, rect: [172,10 141.28125x17.46875] + "follow immediately" + TextNode <#text> + BlockContainer at (458,10) content-size 150x50 flex-item children: inline + line 0 width: 138.296875, height: 17.46875, bottom: 17.46875, baseline: 13.53125 + frag 0 from TextNode start: 0, length: 17, rect: [458,10 138.296875x17.46875] + "over at the right" + TextNode <#text> + BlockContainer <(anonymous)> at (8,62) content-size 784x0 children: inline + TextNode <#text> diff --git a/Tests/LibWeb/Layout/input/flex-margin-auto-justify-content.html b/Tests/LibWeb/Layout/input/flex-margin-auto-justify-content.html new file mode 100644 index 0000000000..ca9d09d255 --- /dev/null +++ b/Tests/LibWeb/Layout/input/flex-margin-auto-justify-content.html @@ -0,0 +1,27 @@ + +
left margin
follow immediately
over at the right
diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp index 2dd053c07c..95abfb3bad 100644 --- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp @@ -1255,82 +1255,83 @@ void FlexFormattingContext::distribute_any_remaining_free_space() CSSPixels initial_offset = 0; auto number_of_items = flex_line.items.size(); + if (auto_margins == 0) { + switch (flex_container().computed_values().justify_content()) { + case CSS::JustifyContent::Start: + case CSS::JustifyContent::FlexStart: + if (is_direction_reverse()) { + initial_offset = inner_main_size(flex_container()); + } else { + initial_offset = 0; + } + break; + case CSS::JustifyContent::End: + case CSS::JustifyContent::FlexEnd: + if (is_direction_reverse()) { + initial_offset = 0; + } else { + initial_offset = inner_main_size(flex_container()); + } + break; + case CSS::JustifyContent::Center: + initial_offset = (inner_main_size(flex_container()) - used_main_space) / 2.0f; + break; + case CSS::JustifyContent::SpaceBetween: + space_between_items = flex_line.remaining_free_space / (number_of_items - 1); + break; + case CSS::JustifyContent::SpaceAround: + space_between_items = flex_line.remaining_free_space / number_of_items; + initial_offset = space_between_items / 2.0f; + break; + } + } + + // For reverse, we use FlexRegionRenderCursor::Right + // to indicate the cursor offset is the end and render backwards + // Otherwise the cursor offset is the 'start' of the region or initial offset enum class FlexRegionRenderCursor { Left, Right }; - auto flex_region_render_cursor = FlexRegionRenderCursor::Left; - bool justification_is_centered = false; switch (flex_container().computed_values().justify_content()) { case CSS::JustifyContent::Start: case CSS::JustifyContent::FlexStart: if (is_direction_reverse()) { flex_region_render_cursor = FlexRegionRenderCursor::Right; - initial_offset = inner_main_size(flex_container()); - } else { - initial_offset = 0; } break; case CSS::JustifyContent::End: case CSS::JustifyContent::FlexEnd: - if (is_direction_reverse()) { - initial_offset = 0; - } else { + if (!is_direction_reverse()) { flex_region_render_cursor = FlexRegionRenderCursor::Right; - initial_offset = inner_main_size(flex_container()); } break; - case CSS::JustifyContent::Center: - initial_offset = (inner_main_size(flex_container()) - used_main_space) / 2.0f; - justification_is_centered = true; - break; - case CSS::JustifyContent::SpaceBetween: - space_between_items = flex_line.remaining_free_space / (number_of_items - 1); - break; - case CSS::JustifyContent::SpaceAround: - space_between_items = flex_line.remaining_free_space / number_of_items; - initial_offset = space_between_items / 2.0f; - justification_is_centered = true; + default: break; } - // For reverse, we use FlexRegionRenderCursor::Right - // to indicate the cursor offset is the end and render backwards - // Otherwise the cursor offset is the 'start' of the region or initial offset CSSPixels cursor_offset = initial_offset; - auto place_item = [&](FlexItem& item, bool is_first_item, bool is_last_item) { - // NOTE: For centered justifications (`center` and `space-around`) we ignore any margin - // before the first item, and after the last item. - - auto item_margin_before = item.margins.main_before; - auto item_margin_after = item.margins.main_after; - if (justification_is_centered) { - if (is_first_item) - item_margin_before = 0; - if (is_last_item) - item_margin_after = 0; - } - + auto place_item = [&](FlexItem& item) { auto amount_of_main_size_used = item.main_size.value() - + item_margin_before + + item.margins.main_before + item.borders.main_before + item.padding.main_before - + item_margin_after + + item.margins.main_after + item.borders.main_after + item.padding.main_after + space_between_items; if (is_direction_reverse()) { - item.main_offset = cursor_offset - item.main_size.value() - item_margin_after - item.borders.main_after - item.padding.main_after; + item.main_offset = cursor_offset - item.main_size.value() - item.margins.main_after - item.borders.main_after - item.padding.main_after; cursor_offset -= amount_of_main_size_used; } else if (flex_region_render_cursor == FlexRegionRenderCursor::Right) { cursor_offset -= amount_of_main_size_used; - item.main_offset = cursor_offset + item_margin_before + item.borders.main_before + item.padding.main_before; + item.main_offset = cursor_offset + item.margins.main_before + item.borders.main_before + item.padding.main_before; } else { - item.main_offset = cursor_offset + item_margin_before + item.borders.main_before + item.padding.main_before; + item.main_offset = cursor_offset + item.margins.main_before + item.borders.main_before + item.padding.main_before; cursor_offset += amount_of_main_size_used; } }; @@ -1338,12 +1339,12 @@ void FlexFormattingContext::distribute_any_remaining_free_space() if (is_direction_reverse() || flex_region_render_cursor == FlexRegionRenderCursor::Right) { for (ssize_t i = flex_line.items.size() - 1; i >= 0; --i) { auto& item = flex_line.items[i]; - place_item(item, i == static_cast(flex_line.items.size()) - 1, i == 0); + place_item(item); } } else { for (size_t i = 0; i < flex_line.items.size(); ++i) { auto& item = flex_line.items[i]; - place_item(item, i == 0, i == flex_line.items.size() - 1); + place_item(item); } } }