LibWeb: Ignore flex container size constraints during intrinsic sizing

Properties like min-width, max-width, etc, should be ignored while we're
trying to determine the intrinsic size of a flex container.

This fixes an infinite recursion when using an intrinsic size keyword as
the max-width of a flex column container.

Note that this behavior is marked as AD-HOC in code comments because
specs don't tell us how to achieve intrinsic sizing.

We can now load product pages on the Twinings site, such as
https://twinings.co.uk/products/earl-grey-100-tea-bags :^)
This commit is contained in:
Andreas Kling 2023-08-01 18:32:08 +02:00
parent f6e4caf197
commit 15440b156f
Notes: sideshowbarker 2024-07-17 10:16:43 +09:00
3 changed files with 23 additions and 6 deletions

View file

@ -0,0 +1,3 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x16 [BFC] children: not-inline
Box <body> at (8,8) content-size 0x0 flex-container(column) [FFC] children: not-inline

View file

@ -0,0 +1,7 @@
<!doctype html><style>
body {
display: flex;
flex-direction: column;
max-width: max-content;
}
</style>

View file

@ -1214,7 +1214,8 @@ void FlexFormattingContext::calculate_cross_size_of_each_flex_line()
// If the flex container is single-line, then clamp the lines cross-size to be within the containers computed min and max cross sizes.
// Note that if CSS 2.1s definition of min/max-width/height applied more generally, this behavior would fall out automatically.
if (is_single_line()) {
// AD-HOC: We don't do this when the flex container is being sized under a min-content or max-content constraint.
if (is_single_line() && !m_available_space_for_flex_container->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;
@ -1530,11 +1531,17 @@ void FlexFormattingContext::determine_flex_container_used_cross_size()
cross_size = cross_size_value.to_px(flex_container(), inner_cross_size(*flex_container().containing_block()));
}
}
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()) : INFINITY;
set_cross_size(flex_container(), css_clamp(cross_size, cross_min_size, cross_max_size));
// 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_flex_container->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()) : INFINITY;
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