LibWeb: Use correct width for flex item intrinsic height calculation

Before this change, we always used the flex container's full available
space as the width for intrinsic (height) sizing of flex items.

This meant that flex lines with more than one flex item had their
intrinsic height determined as if they were alone on the line.

For flex row layouts, if we've already determined the flex item's main
size, we now use that as the width to get the intrinsic height.

This leads to more correct layouts, and also avoids some redundant work
since we no longer do unnecessary sizing work with the wrong width (and
can hit cache instead).
This commit is contained in:
Andreas Kling 2025-09-29 11:03:33 +02:00 committed by Jelle Raaijmakers
parent 6ec10a5408
commit 7867fef8d7
3 changed files with 47 additions and 0 deletions

View File

@ -22,6 +22,14 @@ CSSPixels FlexFormattingContext::get_pixel_width(FlexItem const& item, CSS::Size
CSSPixels FlexFormattingContext::get_pixel_height(FlexItem const& item, CSS::Size const& size) const
{
if (is_row_layout()) {
// NOTE: In a row layout, after we've determined the main size, we use that as the available width
// for any intrinsic sizing layout needed to resolve the height.
auto available_width = item.main_size.has_value() ? AvailableSize::make_definite(item.main_size.value()) : AvailableSize::make_indefinite();
auto available_height = AvailableSize::make_indefinite();
auto available_space = AvailableSpace { available_width, available_height };
return calculate_inner_height(item.box, available_space, size);
}
return calculate_inner_height(item.box, m_available_space.value(), size);
}

View File

@ -0,0 +1,20 @@
Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] children: not-inline
BlockContainer <html> at [0,0] [0+0+0 800 0+0+0] [0+0+0 52 0+0+0] [BFC] children: not-inline
Box <body> at [8,8] flex-container(row) [8+0+0 80 0+0+712] [8+0+0 36 0+0+8] [FFC] children: not-inline
BlockContainer <div.item1> at [8,8] flex-item [0+0+0 71.109375 0+0+0] [0+0+0 36 0+0+0] [BFC] children: inline
frag 0 from TextNode start: 0, length: 7, rect: [8,8 62.796875x18] baseline: 13.796875
"foo bar"
frag 1 from TextNode start: 8, length: 3, rect: [8,26 27.203125x18] baseline: 13.796875
"baz"
TextNode <#text> (not painted)
BlockContainer <div.item2> at [79.109375,8] flex-item [0+0+0 8.890625 0+0+0] [0+0+0 10 0+0+0] [BFC] children: not-inline
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x52]
PaintableBox (Box<BODY>) [8,8 80x36]
PaintableWithLines (BlockContainer<DIV>.item1) [8,8 71.109375x36]
TextPaintable (TextNode<#text>)
PaintableWithLines (BlockContainer<DIV>.item2) [79.109375,8 8.890625x10]
SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto)
SC for BlockContainer<HTML> [0,0 800x52] [children: 0] (z-index: auto)

View File

@ -0,0 +1,19 @@
<!DOCTYPE html><style>
* { outline: 1px solid black; }
html { background: white; }
body {
background: pink;
display: flex;
width: 80px;
}
.item1 {
width: 80px;
height: max-content;
background: orange;
}
.item2 {
background: green;
width: 10px;
height: 10px;
}
</style><body><div class="item1">foo bar baz</div><div class="item2"></div>