LibWeb: Don't include flex line margins in inner flex item cross sizes

In cases where flex item cross size is based on the flex line cross
size, the spec specifically says to transfer the *outer* cross size of
the line. We were ignoring the "outer" part.

This patch fixes that by subtracting the cross margins from the size.
This commit is contained in:
Andreas Kling 2022-07-07 11:44:35 +02:00
parent 030dbfd2a9
commit 8eb022a57d
Notes: sideshowbarker 2024-07-18 00:54:03 +09:00
2 changed files with 25 additions and 2 deletions

View File

@ -170,6 +170,11 @@ void FlexFormattingContext::populate_specified_margins(FlexItem& item, CSS::Flex
item.margins.main_after = item.box.computed_values().margin().right.resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.cross_before = item.box.computed_values().margin().top.resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.cross_after = item.box.computed_values().margin().bottom.resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.main_before_is_auto = item.box.computed_values().margin().left.is_auto();
item.margins.main_after_is_auto = item.box.computed_values().margin().right.is_auto();
item.margins.cross_before_is_auto = item.box.computed_values().margin().top.is_auto();
item.margins.cross_after_is_auto = item.box.computed_values().margin().bottom.is_auto();
} else {
item.borders.main_before = item.box.computed_values().border_top().width;
item.borders.main_after = item.box.computed_values().border_bottom().width;
@ -185,6 +190,11 @@ void FlexFormattingContext::populate_specified_margins(FlexItem& item, CSS::Flex
item.margins.main_after = item.box.computed_values().margin().bottom.resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.cross_before = item.box.computed_values().margin().left.resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.cross_after = item.box.computed_values().margin().right.resolved(item.box, width_of_containing_block_as_length).to_px(item.box);
item.margins.main_before_is_auto = item.box.computed_values().margin().top.is_auto();
item.margins.main_after_is_auto = item.box.computed_values().margin().bottom.is_auto();
item.margins.cross_before_is_auto = item.box.computed_values().margin().left.is_auto();
item.margins.cross_after_is_auto = item.box.computed_values().margin().right.is_auto();
}
};
@ -1067,9 +1077,17 @@ void FlexFormattingContext::determine_used_cross_size_of_each_flex_item()
// FIXME: Get the alignment via "align-self" of the item (which accesses "align-items" of the parent if unset)
for (auto& flex_line : m_flex_lines) {
for (auto& flex_item : flex_line.items) {
if (is_cross_auto(flex_item->box) && flex_container().computed_values().align_items() == CSS::AlignItems::Stretch) {
flex_item->cross_size = flex_line.cross_size;
// If a flex item has align-self: stretch, its computed cross size property is auto,
// and neither of its cross-axis margins are auto, the used outer cross size is the used cross size of its flex line,
// clamped according to the items used min and max cross sizes.
if (flex_item->box.computed_values().align_items() == CSS::AlignItems::Stretch
&& is_cross_auto(flex_item->box)
&& !flex_item->margins.cross_before_is_auto
&& !flex_item->margins.cross_after_is_auto) {
// FIXME: Clamp to the item's used min and max cross sizes.
flex_item->cross_size = flex_line.cross_size - flex_item->margins.cross_before - flex_item->margins.cross_after;
} else {
// Otherwise, the used cross size is the items hypothetical cross size.
flex_item->cross_size = flex_item->hypothetical_cross_size;
}
}

View File

@ -30,6 +30,11 @@ private:
float main_after { 0 };
float cross_before { 0 };
float cross_after { 0 };
bool main_before_is_auto { false };
bool main_after_is_auto { false };
bool cross_before_is_auto { false };
bool cross_after_is_auto { false };
};
struct FlexItem {