LibWeb: Mark flex item main size definite if resolved from aspect-ratio

This matches the behavior of other engines and makes the cards on the
Apple App Store appear in the narrower layouts.
This commit is contained in:
Andreas Kling 2025-11-07 13:34:48 +01:00 committed by Andreas Kling
parent cde3941d9f
commit 6894034774
Notes: github-actions[bot] 2025-11-07 15:43:33 +00:00
4 changed files with 48 additions and 1 deletions

View file

@ -667,6 +667,11 @@ void FlexFormattingContext::determine_flex_base_size(FlexItem& item)
&& item.used_flex_basis->has<CSS::FlexBasisContent>()
&& has_definite_cross_size(item)) {
// flex_base_size is calculated from definite cross size and intrinsic aspect ratio
// AD-HOC: Mark that we resolved the main size from the aspect ratio,
// so that we can mark the item as having definite main size after resolving flexible lengths.
item.main_size_was_resolved_from_aspect_ratio = true;
return adjust_main_size_through_aspect_ratio_for_cross_size_min_max_constraints(
item.box,
calculate_main_size_from_cross_size_and_aspect_ratio(inner_cross_size(item), item.box->preferred_aspect_ratio().value()),
@ -1119,7 +1124,8 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
// https://drafts.csswg.org/css-flexbox-1/#definite-sizes
// 1. If the flex container has a definite main size, then the post-flexing main sizes of its flex items are treated as definite.
// 2. If a flex items flex basis is definite, then its post-flexing main size is also definite.
if (has_definite_main_size(m_flex_container_state) || item.used_flex_basis_is_definite)
// AD-HOC: 3. If a flex items main size was resolved from its intrinsic aspect ratio, then its post-flexing main size is also definite.
if (has_definite_main_size(m_flex_container_state) || item.used_flex_basis_is_definite || item.main_size_was_resolved_from_aspect_ratio)
set_has_definite_main_size(item);
}
}

View file

@ -58,6 +58,7 @@ private:
LayoutState::UsedValues& used_values;
Optional<CSS::FlexBasis> used_flex_basis {};
bool used_flex_basis_is_definite { false };
bool main_size_was_resolved_from_aspect_ratio { false };
CSSPixels flex_base_size { 0 };
CSSPixels hypothetical_main_size { 0 };
CSSPixels hypothetical_cross_size { 0 };

View file

@ -0,0 +1,14 @@
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 400 0+0+400] [0+0+0 400 0+0+0] [BFC] children: not-inline
Box <body> at [8,8] flex-container(column) [8+0+0 400 0+0+-8] [8+0+0 200 0+0+8] [FFC] children: not-inline
BlockContainer <main> at [8,8] flex-item [0+0+0 300 0+0+0] [0+0+0 200 0+0+0] [BFC] children: not-inline
BlockContainer <article> at [8,8] [0+0+0 300 0+0+0] [0+0+0 200 0+0+0] children: not-inline
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 400x400] overflow: [0,0 408x400]
PaintableBox (Box<BODY>) [8,8 400x200]
PaintableWithLines (BlockContainer<MAIN>) [8,8 300x200]
PaintableWithLines (BlockContainer<ARTICLE>) [8,8 300x200]
SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto)
SC for BlockContainer<HTML> [0,0 400x400] [children: 0] (z-index: auto)

View file

@ -0,0 +1,26 @@
<!doctype html><style>
* { outline: 1px solid black; }
html {
background: white;
width: 400px;
height: 400px;
}
body {
display: flex;
flex-direction: column;
width: 400px;
}
main {
background-color: magenta;
aspect-ratio: 3 / 2;
width: 300px;
}
article {
background-color: pink;
height: 100%;
}
div {
background-color: orange;
position: absolute;
}
</style><body><main><article>