Bläddra i källkod

LibWeb: Resolve flex item percentages against used flex container sizes

Once we've resolved the used flex item width & height, we should allow
percentage flex item sizes to resolve against them instead of forcing
flex items to always treat percentages as auto while doing intrinsic
sizing layout.

Regressed in 8dd489da61362738a39ec938732e3d054ff5da8b.
Andreas Kling 2 år sedan
förälder
incheckning
ac124fbaae

+ 11 - 0
Tests/LibWeb/Layout/expected/flex/flex-column-item-with-percentage-max-width.txt

@@ -0,0 +1,11 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (1,1) content-size 798x120 [BFC] children: not-inline
+    BlockContainer <body> at (10,10) content-size 54x102 children: not-inline
+      Box <div.flex> at (11,11) content-size 52x100 flex-container(column) [FFC] children: not-inline
+        BlockContainer <div.hmm> at (12,12) content-size 50x17.46875 flex-item [BFC] children: inline
+          line 0 width: 39.78125, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+            frag 0 from TextNode start: 0, length: 5, rect: [12,12 39.78125x17.46875]
+              "Hello"
+          TextNode <#text>
+        BlockContainer <(anonymous)> (not painted) [BFC] children: inline
+          TextNode <#text>

+ 24 - 0
Tests/LibWeb/Layout/input/flex/flex-column-item-with-percentage-max-width.html

@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<style>
+  * {
+    border: 1px solid black;
+    background: none;
+    color: black;
+  }
+  .flex {
+    display: flex;
+    flex-direction: column;
+    background: pink;
+    height: 100px;
+  }
+  .hmm {
+    max-width: 100%;
+    width: 50px;
+    background: orange;
+  }
+  body {
+    width: max-content;
+    background: white;
+  }
+</style>
+<body><div class="flex"><div class="hmm">Hello</div>

+ 50 - 50
Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp

@@ -27,14 +27,14 @@ template<typename T>
     return ::max(min, ::min(value, max));
     return ::max(min, ::min(value, max));
 }
 }
 
 
-CSSPixels FlexFormattingContext::get_pixel_width(Box const& box, AvailableSpace const& available_space, CSS::Size const& size) const
+CSSPixels FlexFormattingContext::get_pixel_width(Box const& box, CSS::Size const& size) const
 {
 {
-    return calculate_inner_width(box, available_space.width, size).to_px(box);
+    return calculate_inner_width(box, containing_block_width_as_available_size(box), size).to_px(box);
 }
 }
 
 
-CSSPixels FlexFormattingContext::get_pixel_height(Box const& box, AvailableSpace const& available_space, CSS::Size const& size) const
+CSSPixels FlexFormattingContext::get_pixel_height(Box const& box, CSS::Size const& size) const
 {
 {
-    return calculate_inner_height(box, available_space.height, size).to_px(box);
+    return calculate_inner_height(box, containing_block_height_as_available_size(box), size).to_px(box);
 }
 }
 
 
 FlexFormattingContext::FlexFormattingContext(LayoutState& state, Box const& flex_container, FormattingContext* parent)
 FlexFormattingContext::FlexFormattingContext(LayoutState& state, Box const& flex_container, FormattingContext* parent)
@@ -96,8 +96,8 @@ void FlexFormattingContext::run(Box const& run_box, LayoutMode, AvailableSpace c
             for (auto& item : m_flex_items) {
             for (auto& item : m_flex_items) {
                 if (!flex_item_is_stretched(item))
                 if (!flex_item_is_stretched(item))
                     continue;
                     continue;
-                auto item_min_cross_size = has_cross_min_size(item.box) ? specified_cross_min_size(item.box, m_available_space_for_items->space) : 0;
-                auto item_max_cross_size = has_cross_max_size(item.box) ? specified_cross_max_size(item.box, m_available_space_for_items->space) : INFINITY;
+                auto item_min_cross_size = has_cross_min_size(item.box) ? specified_cross_min_size(item.box) : 0;
+                auto item_max_cross_size = has_cross_max_size(item.box) ? specified_cross_max_size(item.box) : INFINITY;
                 auto item_preferred_outer_cross_size = css_clamp(flex_container_inner_cross_size, item_min_cross_size, item_max_cross_size);
                 auto item_preferred_outer_cross_size = css_clamp(flex_container_inner_cross_size, item_min_cross_size, item_max_cross_size);
                 auto item_inner_cross_size = item_preferred_outer_cross_size - item.margins.cross_before - item.margins.cross_after - item.padding.cross_before - item.padding.cross_after - item.borders.cross_before - item.borders.cross_after;
                 auto item_inner_cross_size = item_preferred_outer_cross_size - item.margins.cross_before - item.margins.cross_after - item.padding.cross_before - item.padding.cross_after - item.borders.cross_before - item.borders.cross_after;
                 set_cross_size(item.box, item_inner_cross_size);
                 set_cross_size(item.box, item_inner_cross_size);
@@ -352,18 +352,18 @@ bool FlexFormattingContext::has_definite_cross_size(Box const& box) const
     return is_row_layout() ? used_values.has_definite_height() : used_values.has_definite_width();
     return is_row_layout() ? used_values.has_definite_height() : used_values.has_definite_width();
 }
 }
 
 
-CSSPixels FlexFormattingContext::specified_main_min_size(Box const& box, AvailableSpace const& available_space) const
+CSSPixels FlexFormattingContext::specified_main_min_size(Box const& box) const
 {
 {
     return is_row_layout()
     return is_row_layout()
-        ? get_pixel_width(box, available_space, box.computed_values().min_width())
-        : get_pixel_height(box, available_space, box.computed_values().min_height());
+        ? get_pixel_width(box, box.computed_values().min_width())
+        : get_pixel_height(box, box.computed_values().min_height());
 }
 }
 
 
-CSSPixels FlexFormattingContext::specified_cross_min_size(Box const& box, AvailableSpace const& available_space) const
+CSSPixels FlexFormattingContext::specified_cross_min_size(Box const& box) const
 {
 {
     return is_row_layout()
     return is_row_layout()
-        ? get_pixel_height(box, available_space, box.computed_values().min_height())
-        : get_pixel_width(box, available_space, box.computed_values().min_width());
+        ? get_pixel_height(box, box.computed_values().min_height())
+        : get_pixel_width(box, box.computed_values().min_width());
 }
 }
 
 
 bool FlexFormattingContext::has_main_max_size(Box const& box) const
 bool FlexFormattingContext::has_main_max_size(Box const& box) const
@@ -378,18 +378,18 @@ bool FlexFormattingContext::has_cross_max_size(Box const& box) const
     return !value.is_none();
     return !value.is_none();
 }
 }
 
 
-CSSPixels FlexFormattingContext::specified_main_max_size(Box const& box, AvailableSpace const& available_space) const
+CSSPixels FlexFormattingContext::specified_main_max_size(Box const& box) const
 {
 {
     return is_row_layout()
     return is_row_layout()
-        ? get_pixel_width(box, available_space, box.computed_values().max_width())
-        : get_pixel_height(box, available_space, box.computed_values().max_height());
+        ? get_pixel_width(box, box.computed_values().max_width())
+        : get_pixel_height(box, box.computed_values().max_height());
 }
 }
 
 
-CSSPixels FlexFormattingContext::specified_cross_max_size(Box const& box, AvailableSpace const& available_space) const
+CSSPixels FlexFormattingContext::specified_cross_max_size(Box const& box) const
 {
 {
     return is_row_layout()
     return is_row_layout()
-        ? get_pixel_height(box, available_space, box.computed_values().max_height())
-        : get_pixel_width(box, available_space, box.computed_values().max_width());
+        ? get_pixel_height(box, box.computed_values().max_height())
+        : get_pixel_width(box, box.computed_values().max_width());
 }
 }
 
 
 bool FlexFormattingContext::is_cross_auto(Box const& box) const
 bool FlexFormattingContext::is_cross_auto(Box const& box) const
@@ -608,8 +608,8 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size(
         if (item.used_flex_basis_is_definite) {
         if (item.used_flex_basis_is_definite) {
             auto const& size = item.used_flex_basis->get<CSS::Size>();
             auto const& size = item.used_flex_basis->get<CSS::Size>();
             if (is_row_layout())
             if (is_row_layout())
-                return get_pixel_width(child_box, m_available_space_for_items->space, size);
-            return get_pixel_height(child_box, m_available_space_for_items->space, size);
+                return get_pixel_width(child_box, size);
+            return get_pixel_height(child_box, size);
         }
         }
 
 
         // B. If the flex item has ...
         // B. If the flex item has ...
@@ -687,8 +687,8 @@ void FlexFormattingContext::determine_flex_base_size_and_hypothetical_main_size(
     }
     }
 
 
     // The hypothetical main size is the item’s flex base size clamped according to its used min and max main sizes (and flooring the content box size at zero).
     // The hypothetical main size is the item’s flex base size clamped according to its used min and max main sizes (and flooring the content box size at zero).
-    auto clamp_min = has_main_min_size(child_box) ? specified_main_min_size(child_box, m_available_space_for_items->space) : automatic_minimum_size(item);
-    auto clamp_max = has_main_max_size(child_box) ? specified_main_max_size(child_box, m_available_space_for_items->space) : NumericLimits<float>::max();
+    auto clamp_min = has_main_min_size(child_box) ? specified_main_min_size(child_box) : automatic_minimum_size(item);
+    auto clamp_max = has_main_max_size(child_box) ? specified_main_max_size(child_box) : NumericLimits<float>::max();
     item.hypothetical_main_size = max(CSSPixels(0), css_clamp(item.flex_base_size, clamp_min, clamp_max));
     item.hypothetical_main_size = max(CSSPixels(0), css_clamp(item.flex_base_size, clamp_min, clamp_max));
 
 
     // NOTE: At this point, we set the hypothetical main size as the flex item's *temporary* main size.
     // NOTE: At this point, we set the hypothetical main size as the flex item's *temporary* main size.
@@ -721,7 +721,7 @@ Optional<CSSPixels> FlexFormattingContext::specified_size_suggestion(FlexItem co
     // then the specified size suggestion is that size. It is otherwise undefined.
     // then the specified size suggestion is that size. It is otherwise undefined.
     if (has_definite_main_size(item.box) && !should_treat_main_size_as_auto(item.box)) {
     if (has_definite_main_size(item.box) && !should_treat_main_size_as_auto(item.box)) {
         // NOTE: We use get_pixel_{width,height} to ensure that CSS box-sizing is respected.
         // NOTE: We use get_pixel_{width,height} to ensure that CSS box-sizing is respected.
-        return is_row_layout() ? get_pixel_width(item.box, m_available_space_for_items->space, computed_main_size(item.box)) : get_pixel_height(item.box, m_available_space_for_items->space, computed_main_size(item.box));
+        return is_row_layout() ? get_pixel_width(item.box, computed_main_size(item.box)) : get_pixel_height(item.box, computed_main_size(item.box));
     }
     }
     return {};
     return {};
 }
 }
@@ -781,7 +781,7 @@ CSSPixels FlexFormattingContext::content_based_minimum_size(FlexItem const& item
 
 
     // In all cases, the size is clamped by the maximum main size if it’s definite.
     // In all cases, the size is clamped by the maximum main size if it’s definite.
     if (has_main_max_size(item.box)) {
     if (has_main_max_size(item.box)) {
-        return min(unclamped_size, specified_main_max_size(item.box, m_available_space_for_items->space));
+        return min(unclamped_size, specified_main_max_size(item.box));
     }
     }
     return unclamped_size;
     return unclamped_size;
 }
 }
@@ -1036,11 +1036,11 @@ void FlexFormattingContext::resolve_flexible_lengths_for_line(FlexLine& line)
             if (item.frozen)
             if (item.frozen)
                 continue;
                 continue;
             auto used_min_main_size = has_main_min_size(item.box)
             auto used_min_main_size = has_main_min_size(item.box)
-                ? specified_main_min_size(item.box, m_available_space_for_items->space)
+                ? specified_main_min_size(item.box)
                 : automatic_minimum_size(item);
                 : automatic_minimum_size(item);
 
 
             auto used_max_main_size = has_main_max_size(item.box)
             auto used_max_main_size = has_main_max_size(item.box)
-                ? specified_main_max_size(item.box, m_available_space_for_items->space)
+                ? specified_main_max_size(item.box)
                 : NumericLimits<float>::max();
                 : NumericLimits<float>::max();
 
 
             auto original_target_main_size = item.target_main_size;
             auto original_target_main_size = item.target_main_size;
@@ -1124,8 +1124,8 @@ void FlexFormattingContext::determine_hypothetical_cross_size_of_item(FlexItem&
     auto const& computed_min_size = this->computed_cross_min_size(item.box);
     auto const& computed_min_size = this->computed_cross_min_size(item.box);
     auto const& computed_max_size = this->computed_cross_max_size(item.box);
     auto const& computed_max_size = this->computed_cross_max_size(item.box);
 
 
-    auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box, m_available_space_for_items->space) : 0;
-    auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box, m_available_space_for_items->space) : NumericLimits<float>::max();
+    auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box) : 0;
+    auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : NumericLimits<float>::max();
 
 
     // If we have a definite cross size, this is easy! No need to perform layout, we can just use it as-is.
     // If we have a definite cross size, this is easy! No need to perform layout, we can just use it as-is.
     if (has_definite_cross_size(item.box)) {
     if (has_definite_cross_size(item.box)) {
@@ -1218,8 +1218,8 @@ void FlexFormattingContext::calculate_cross_size_of_each_flex_line()
     if (is_single_line()) {
     if (is_single_line()) {
         auto const& computed_min_size = this->computed_cross_min_size(flex_container());
         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 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(), m_available_space_for_flex_container->space) : 0;
-        auto cross_max_size = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_cross_max_size(flex_container(), m_available_space_for_flex_container->space) : INFINITY;
+        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;
         m_flex_lines[0].cross_size = css_clamp(m_flex_lines[0].cross_size, cross_min_size, cross_max_size);
         m_flex_lines[0].cross_size = css_clamp(m_flex_lines[0].cross_size, cross_min_size, cross_max_size);
     }
     }
 }
 }
@@ -1243,8 +1243,8 @@ void FlexFormattingContext::determine_used_cross_size_of_each_flex_item()
 
 
                 auto const& computed_min_size = computed_cross_min_size(item.box);
                 auto const& computed_min_size = computed_cross_min_size(item.box);
                 auto const& computed_max_size = computed_cross_max_size(item.box);
                 auto const& computed_max_size = computed_cross_max_size(item.box);
-                auto cross_min_size = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_cross_min_size(item.box, m_available_space_for_items->space) : 0;
-                auto cross_max_size = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_cross_max_size(item.box, m_available_space_for_items->space) : INFINITY;
+                auto cross_min_size = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_cross_min_size(item.box) : 0;
+                auto cross_max_size = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_cross_max_size(item.box) : INFINITY;
 
 
                 item.cross_size = css_clamp(unclamped_cross_size, cross_min_size, cross_max_size);
                 item.cross_size = css_clamp(unclamped_cross_size, cross_min_size, cross_max_size);
             } else {
             } else {
@@ -1519,8 +1519,8 @@ void FlexFormattingContext::determine_flex_container_used_cross_size()
     }
     }
     auto const& computed_min_size = this->computed_cross_min_size(flex_container());
     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 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(), m_available_space_for_flex_container->space) : 0;
-    auto cross_max_size = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_cross_max_size(flex_container(), m_available_space_for_flex_container->space) : INFINITY;
+    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));
     set_cross_size(flex_container(), css_clamp(cross_size, cross_min_size, cross_max_size));
 }
 }
 
 
@@ -1762,8 +1762,8 @@ CSSPixels FlexFormattingContext::calculate_intrinsic_main_size_of_flex_container
                 auto const& computed_min_size = this->computed_main_min_size(item.box);
                 auto const& computed_min_size = this->computed_main_min_size(item.box);
                 auto const& computed_max_size = this->computed_main_max_size(item.box);
                 auto const& computed_max_size = this->computed_main_max_size(item.box);
 
 
-                auto clamp_min = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_main_min_size(item.box, m_available_space_for_items->space) : automatic_minimum_size(item);
-                auto clamp_max = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_main_max_size(item.box, m_available_space_for_items->space) : NumericLimits<float>::max();
+                auto clamp_min = (!computed_min_size.is_auto() && !computed_min_size.contains_percentage()) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
+                auto clamp_max = (!computed_max_size.is_none() && !computed_max_size.contains_percentage()) ? specified_main_max_size(item.box) : NumericLimits<float>::max();
 
 
                 result = css_clamp(result, clamp_min, clamp_max);
                 result = css_clamp(result, clamp_min, clamp_max);
 
 
@@ -1865,12 +1865,12 @@ CSSPixels FlexFormattingContext::calculate_main_min_content_contribution(FlexIte
         auto inner_min_content_size = calculate_min_content_main_size(item);
         auto inner_min_content_size = calculate_min_content_main_size(item);
         if (computed_main_size(item.box).is_auto())
         if (computed_main_size(item.box).is_auto())
             return inner_min_content_size;
             return inner_min_content_size;
-        auto inner_preferred_size = is_row_layout() ? get_pixel_width(item.box, m_available_space_for_items->space, computed_main_size(item.box)) : get_pixel_height(item.box, m_available_space_for_items->space, computed_main_size(item.box));
+        auto inner_preferred_size = is_row_layout() ? get_pixel_width(item.box, computed_main_size(item.box)) : get_pixel_height(item.box, computed_main_size(item.box));
         return max(inner_min_content_size, inner_preferred_size);
         return max(inner_min_content_size, inner_preferred_size);
     }();
     }();
 
 
-    auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box, m_available_space_for_items->space) : automatic_minimum_size(item);
-    auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box, m_available_space_for_items->space) : NumericLimits<float>::max();
+    auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
+    auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits<float>::max();
     auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max);
     auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max);
 
 
     return item.add_main_margin_box_sizes(clamped_inner_size);
     return item.add_main_margin_box_sizes(clamped_inner_size);
@@ -1886,12 +1886,12 @@ CSSPixels FlexFormattingContext::calculate_main_max_content_contribution(FlexIte
         auto inner_max_content_size = calculate_max_content_main_size(item);
         auto inner_max_content_size = calculate_max_content_main_size(item);
         if (computed_main_size(item.box).is_auto())
         if (computed_main_size(item.box).is_auto())
             return inner_max_content_size;
             return inner_max_content_size;
-        auto inner_preferred_size = is_row_layout() ? get_pixel_width(item.box, m_available_space_for_items->space, computed_main_size(item.box)) : get_pixel_height(item.box, m_available_space_for_items->space, computed_main_size(item.box));
+        auto inner_preferred_size = is_row_layout() ? get_pixel_width(item.box, computed_main_size(item.box)) : get_pixel_height(item.box, computed_main_size(item.box));
         return max(inner_max_content_size, inner_preferred_size);
         return max(inner_max_content_size, inner_preferred_size);
     }();
     }();
 
 
-    auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box, m_available_space_for_items->space) : automatic_minimum_size(item);
-    auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box, m_available_space_for_items->space) : NumericLimits<float>::max();
+    auto clamp_min = has_main_min_size(item.box) ? specified_main_min_size(item.box) : automatic_minimum_size(item);
+    auto clamp_max = has_main_max_size(item.box) ? specified_main_max_size(item.box) : NumericLimits<float>::max();
     auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max);
     auto clamped_inner_size = css_clamp(larger_size, clamp_min, clamp_max);
 
 
     return item.add_main_margin_box_sizes(clamped_inner_size);
     return item.add_main_margin_box_sizes(clamped_inner_size);
@@ -1916,14 +1916,14 @@ CSSPixels FlexFormattingContext::calculate_cross_min_content_contribution(FlexIt
     auto size = [&] {
     auto size = [&] {
         if (should_treat_cross_size_as_auto(item.box))
         if (should_treat_cross_size_as_auto(item.box))
             return calculate_min_content_cross_size(item);
             return calculate_min_content_cross_size(item);
-        return !is_row_layout() ? get_pixel_width(item.box, m_available_space_for_items->space, computed_cross_size(item.box)) : get_pixel_height(item.box, m_available_space_for_items->space, computed_cross_size(item.box));
+        return !is_row_layout() ? get_pixel_width(item.box, computed_cross_size(item.box)) : get_pixel_height(item.box, computed_cross_size(item.box));
     }();
     }();
 
 
     auto const& computed_min_size = this->computed_cross_min_size(item.box);
     auto const& computed_min_size = this->computed_cross_min_size(item.box);
     auto const& computed_max_size = this->computed_cross_max_size(item.box);
     auto const& computed_max_size = this->computed_cross_max_size(item.box);
 
 
-    auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box, m_available_space_for_items->space) : 0;
-    auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box, m_available_space_for_items->space) : NumericLimits<float>::max();
+    auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box) : 0;
+    auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : NumericLimits<float>::max();
 
 
     auto clamped_inner_size = css_clamp(size, clamp_min, clamp_max);
     auto clamped_inner_size = css_clamp(size, clamp_min, clamp_max);
 
 
@@ -1935,14 +1935,14 @@ CSSPixels FlexFormattingContext::calculate_cross_max_content_contribution(FlexIt
     auto size = [&] {
     auto size = [&] {
         if (should_treat_cross_size_as_auto(item.box))
         if (should_treat_cross_size_as_auto(item.box))
             return calculate_max_content_cross_size(item);
             return calculate_max_content_cross_size(item);
-        return !is_row_layout() ? get_pixel_width(item.box, m_available_space_for_items->space, computed_cross_size(item.box)) : get_pixel_height(item.box, m_available_space_for_items->space, computed_cross_size(item.box));
+        return !is_row_layout() ? get_pixel_width(item.box, computed_cross_size(item.box)) : get_pixel_height(item.box, computed_cross_size(item.box));
     }();
     }();
 
 
     auto const& computed_min_size = this->computed_cross_min_size(item.box);
     auto const& computed_min_size = this->computed_cross_min_size(item.box);
     auto const& computed_max_size = this->computed_cross_max_size(item.box);
     auto const& computed_max_size = this->computed_cross_max_size(item.box);
 
 
-    auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box, m_available_space_for_items->space) : 0;
-    auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box, m_available_space_for_items->space) : NumericLimits<float>::max();
+    auto clamp_min = (!computed_min_size.is_auto() && (resolve_percentage_min_max_sizes || !computed_min_size.contains_percentage())) ? specified_cross_min_size(item.box) : 0;
+    auto clamp_max = (!computed_max_size.is_none() && (resolve_percentage_min_max_sizes || !computed_max_size.contains_percentage())) ? specified_cross_max_size(item.box) : NumericLimits<float>::max();
 
 
     auto clamped_inner_size = css_clamp(size, clamp_min, clamp_max);
     auto clamped_inner_size = css_clamp(size, clamp_min, clamp_max);
 
 
@@ -1953,8 +1953,8 @@ CSSPixels FlexFormattingContext::calculate_clamped_fit_content_width(Box const&
 {
 {
     auto const& computed_min_size = box.computed_values().min_width();
     auto const& computed_min_size = box.computed_values().min_width();
     auto const& computed_max_size = box.computed_values().max_width();
     auto const& computed_max_size = box.computed_values().max_width();
-    auto clamp_min = (!computed_min_size.is_auto() && (!computed_min_size.contains_percentage())) ? specified_cross_min_size(box, m_available_space_for_items->space) : 0;
-    auto clamp_max = (!computed_max_size.is_none() && (!computed_max_size.contains_percentage())) ? specified_cross_max_size(box, m_available_space_for_items->space) : NumericLimits<float>::max();
+    auto clamp_min = (!computed_min_size.is_auto() && (!computed_min_size.contains_percentage())) ? specified_cross_min_size(box) : 0;
+    auto clamp_max = (!computed_max_size.is_none() && (!computed_max_size.contains_percentage())) ? specified_cross_max_size(box) : NumericLimits<float>::max();
     auto size = FormattingContext::calculate_fit_content_width(box, available_space);
     auto size = FormattingContext::calculate_fit_content_width(box, available_space);
     return css_clamp(size, clamp_min, clamp_max);
     return css_clamp(size, clamp_min, clamp_max);
 }
 }

+ 6 - 6
Userland/Libraries/LibWeb/Layout/FlexFormattingContext.h

@@ -124,11 +124,11 @@ private:
     CSSPixels inner_cross_size(Box const&) const;
     CSSPixels inner_cross_size(Box const&) const;
     bool has_main_min_size(Box const&) const;
     bool has_main_min_size(Box const&) const;
     bool has_cross_min_size(Box const&) const;
     bool has_cross_min_size(Box const&) const;
-    CSSPixels specified_main_max_size(Box const&, AvailableSpace const&) const;
-    CSSPixels specified_cross_max_size(Box const&, AvailableSpace const&) const;
+    CSSPixels specified_main_max_size(Box const&) const;
+    CSSPixels specified_cross_max_size(Box const&) const;
     bool is_cross_auto(Box const&) const;
     bool is_cross_auto(Box const&) const;
-    CSSPixels specified_main_min_size(Box const&, AvailableSpace const&) const;
-    CSSPixels specified_cross_min_size(Box const&, AvailableSpace const&) const;
+    CSSPixels specified_main_min_size(Box const&) const;
+    CSSPixels specified_cross_min_size(Box const&) const;
     bool has_main_max_size(Box const&) const;
     bool has_main_max_size(Box const&) const;
     bool has_cross_max_size(Box const&) const;
     bool has_cross_max_size(Box const&) const;
     CSSPixels automatic_minimum_size(FlexItem const&) const;
     CSSPixels automatic_minimum_size(FlexItem const&) const;
@@ -143,8 +143,8 @@ private:
     CSS::Size const& computed_cross_min_size(Box const&) const;
     CSS::Size const& computed_cross_min_size(Box const&) const;
     CSS::Size const& computed_cross_max_size(Box const&) const;
     CSS::Size const& computed_cross_max_size(Box const&) const;
 
 
-    CSSPixels get_pixel_width(Box const&, AvailableSpace const&, CSS::Size const&) const;
-    CSSPixels get_pixel_height(Box const&, AvailableSpace const&, CSS::Size const&) const;
+    CSSPixels get_pixel_width(Box const&, CSS::Size const&) const;
+    CSSPixels get_pixel_height(Box const&, CSS::Size const&) const;
 
 
     bool flex_item_is_stretched(FlexItem const&) const;
     bool flex_item_is_stretched(FlexItem const&) const;
 
 

+ 32 - 0
Userland/Libraries/LibWeb/Layout/FormattingContext.cpp

@@ -1566,6 +1566,38 @@ CSSPixels FormattingContext::containing_block_height_for(Box const& box) const
     VERIFY_NOT_REACHED();
     VERIFY_NOT_REACHED();
 }
 }
 
 
+AvailableSize FormattingContext::containing_block_width_as_available_size(Box const& box) const
+{
+    auto const& containing_block_state = m_state.get(*box.containing_block());
+    auto const& box_state = m_state.get(box);
+
+    switch (box_state.width_constraint) {
+    case SizeConstraint::MinContent:
+        return AvailableSize::make_min_content();
+    case SizeConstraint::MaxContent:
+        return AvailableSize::make_max_content();
+    case SizeConstraint::None:
+        return AvailableSize::make_definite(containing_block_state.content_width());
+    }
+    VERIFY_NOT_REACHED();
+}
+
+AvailableSize FormattingContext::containing_block_height_as_available_size(Box const& box) const
+{
+    auto const& containing_block_state = m_state.get(*box.containing_block());
+    auto const& box_state = m_state.get(box);
+
+    switch (box_state.height_constraint) {
+    case SizeConstraint::MinContent:
+        return AvailableSize::make_min_content();
+    case SizeConstraint::MaxContent:
+        return AvailableSize::make_max_content();
+    case SizeConstraint::None:
+        return AvailableSize::make_definite(containing_block_state.content_height());
+    }
+    VERIFY_NOT_REACHED();
+}
+
 // https://drafts.csswg.org/css-sizing-3/#stretch-fit-size
 // https://drafts.csswg.org/css-sizing-3/#stretch-fit-size
 CSSPixels FormattingContext::calculate_stretch_fit_width(Box const& box, AvailableSize const& available_width) const
 CSSPixels FormattingContext::calculate_stretch_fit_width(Box const& box, AvailableSize const& available_width) const
 {
 {

+ 3 - 0
Userland/Libraries/LibWeb/Layout/FormattingContext.h

@@ -83,6 +83,9 @@ public:
     [[nodiscard]] CSSPixels containing_block_width_for(Box const&) const;
     [[nodiscard]] CSSPixels containing_block_width_for(Box const&) const;
     [[nodiscard]] CSSPixels containing_block_height_for(Box const&) const;
     [[nodiscard]] CSSPixels containing_block_height_for(Box const&) const;
 
 
+    [[nodiscard]] AvailableSize containing_block_width_as_available_size(Box const&) const;
+    [[nodiscard]] AvailableSize containing_block_height_as_available_size(Box const&) const;
+
     [[nodiscard]] CSSPixels calculate_stretch_fit_width(Box const&, AvailableSize const&) const;
     [[nodiscard]] CSSPixels calculate_stretch_fit_width(Box const&, AvailableSize const&) const;
     [[nodiscard]] CSSPixels calculate_stretch_fit_height(Box const&, AvailableSize const&) const;
     [[nodiscard]] CSSPixels calculate_stretch_fit_height(Box const&, AvailableSize const&) const;