LibWeb: Don't make flex layout responsible for flex container cross size

Although the flex algorithm as specified does say to determine the cross
size of the flex container, this is not how our layout engine works.

The parent formatting context is responsible for sizing its children,
and since that's already happening, we can simply remove the cross
sizing step from FFC.
This commit is contained in:
Andreas Kling 2024-03-26 20:17:07 +01:00
parent ead341738e
commit d37c0a2cab
Notes: sideshowbarker 2024-07-16 22:18:54 +09:00
6 changed files with 36 additions and 54 deletions

View file

@ -0,0 +1,13 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x116 [BFC] children: not-inline
Box <body> at (8,8) content-size 100x100 flex-container(row) [FFC] children: not-inline
BlockContainer <(anonymous)> at (8,8) content-size 9.46875x100 flex-item [BFC] children: inline
frag 0 from TextNode start: 0, length: 1, rect: [8,8 9.46875x17] baseline: 13.296875
"b"
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x116]
PaintableBox (Box<BODY>) [8,8 100x100]
PaintableWithLines (BlockContainer(anonymous)) [8,8 9.46875x100]
TextPaintable (TextNode<#text>)

View file

@ -1,11 +1,11 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (1,1) content-size 798x69.984375 [BFC] children: not-inline
Box <body> at (10,10) content-size 780x51.984375 flex-container(row) [FFC] children: not-inline
ImageBox <img> at (11,11) content-size 66.65625x50 flex-item children: not-inline
ImageBox <img> at (11,10) content-size 66.65625x50 flex-item children: not-inline
BlockContainer <(anonymous)> (not painted) [BFC] children: inline
TextNode <#text>
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x71.984375]
PaintableBox (Box<BODY>) [9,9 782x53.984375] overflow: [10,10 780x52]
ImagePaintable (ImageBox<IMG>) [10,10 68.65625x52]
PaintableBox (Box<BODY>) [9,9 782x53.984375] overflow: [10,9 780x52.984375]
ImagePaintable (ImageBox<IMG>) [10,9 68.65625x52]

View file

@ -1,15 +1,15 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x33 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x17 children: inline
frag 0 from Box start: 0, length: 0, rect: [8,8 10x10.3125] baseline: 13.296875
Box <div.inline-flex.aspect-ratio> at (8,8) content-size 10x10.3125 flex-container(row) [FFC] children: not-inline
BlockContainer <div.img-wrapper> at (8,8) content-size 10x17 flex-item [BFC] children: inline
frag 0 from ImageBox start: 0, length: 0, rect: [8,11 10x10] baseline: 10
ImageBox <img> at (8,11) content-size 10x10 children: not-inline
frag 0 from Box start: 0, length: 0, rect: [8,11 10x10.3125] baseline: 9.953125
Box <div.inline-flex.aspect-ratio> at (8,11) content-size 10x10.3125 flex-container(row) [FFC] children: not-inline
BlockContainer <div.img-wrapper> at (8,7.65625) content-size 10x17 flex-item [BFC] children: inline
frag 0 from ImageBox start: 0, length: 0, rect: [8,10.65625 10x10] baseline: 10
ImageBox <img> at (8,10.65625) content-size 10x10 children: not-inline
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x33]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x17]
PaintableBox (Box<DIV>.inline-flex.aspect-ratio) [8,8 10x10.3125] overflow: [8,8 10x17]
PaintableWithLines (BlockContainer<DIV>.img-wrapper) [8,8 10x17]
ImagePaintable (ImageBox<IMG>) [8,11 10x10]
PaintableBox (Box<DIV>.inline-flex.aspect-ratio) [8,11 10x10.3125] overflow: [8,7.65625 10x17]
PaintableWithLines (BlockContainer<DIV>.img-wrapper) [8,7.65625 10x17]
ImagePaintable (ImageBox<IMG>) [8,10.65625 10x10]

View file

@ -0,0 +1,10 @@
<!DOCTYPE html><style>
* {
outline: 1px solid black;
}
body {
aspect-ratio: 1;
width: 100px;
display: flex;
}
</style>b

View file

@ -143,8 +143,8 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode, AvailableSpace c
// 14. Align all flex items along the cross-axis
align_all_flex_items_along_the_cross_axis();
// 15. Determine the flex containers used cross size:
determine_flex_container_used_cross_size();
// 15. Determine the flex containers used cross size
// NOTE: This is handled by the parent formatting context.
{
// https://drafts.csswg.org/css-flexbox-1/#definite-sizes
@ -1435,45 +1435,6 @@ void FlexFormattingContext::align_all_flex_items_along_the_cross_axis()
}
}
// https://www.w3.org/TR/css-flexbox-1/#algo-cross-container
void FlexFormattingContext::determine_flex_container_used_cross_size()
{
CSSPixels cross_size = 0;
if (has_definite_cross_size(m_flex_container_state)) {
// Flex container has definite cross size: easy-peasy.
cross_size = inner_cross_size(m_flex_container_state);
} else {
// Flex container has indefinite cross size.
auto cross_size_value = is_row_layout() ? flex_container().computed_values().height() : flex_container().computed_values().width();
if (cross_size_value.is_auto() || cross_size_value.contains_percentage()) {
// If a content-based cross size is needed, use the sum of the flex lines' cross sizes.
CSSPixels sum_of_flex_lines_cross_sizes = 0;
for (auto& flex_line : m_flex_lines) {
sum_of_flex_lines_cross_sizes += flex_line.cross_size;
}
cross_size = sum_of_flex_lines_cross_sizes;
if (cross_size_value.contains_percentage()) {
// FIXME: Handle percentage values here! Right now we're just treating them as "auto"
}
} else {
// Otherwise, resolve the indefinite size at this point.
cross_size = cross_size_value.to_px(flex_container(), inner_cross_size(m_state.get(*flex_container().containing_block())));
}
}
// AD-HOC: We don't apply min/max cross size constraints when sizing the flex container under an intrinsic sizing constraint.
if (!m_available_space_for_items->cross.is_intrinsic_sizing_constraint()) {
auto const& computed_min_size = this->computed_cross_min_size(flex_container());
auto const& computed_max_size = this->computed_cross_max_size(flex_container());
auto cross_min_size = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_cross_min_size(flex_container()) : 0;
auto cross_max_size = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_cross_max_size(flex_container()) : CSSPixels::max();
set_cross_size(flex_container(), css_clamp(cross_size, cross_min_size, cross_max_size));
} else {
set_cross_size(flex_container(), cross_size);
}
}
// https://www.w3.org/TR/css-flexbox-1/#algo-line-align
void FlexFormattingContext::align_all_flex_lines()
{

View file

@ -191,8 +191,6 @@ private:
void align_all_flex_items_along_the_cross_axis();
void determine_flex_container_used_cross_size();
void align_all_flex_lines();
bool is_row_layout() const { return m_flex_direction == CSS::FlexDirection::Row || m_flex_direction == CSS::FlexDirection::RowReverse; }