diff --git a/Tests/LibWeb/Layout/expected/abspos-flex-container-with-auto-height.txt b/Tests/LibWeb/Layout/expected/abspos-flex-container-with-auto-height.txt
new file mode 100644
index 0000000000..85ce72af3c
--- /dev/null
+++ b/Tests/LibWeb/Layout/expected/abspos-flex-container-with-auto-height.txt
@@ -0,0 +1,8 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+ BlockContainer at (1,1) content-size 798x0 [BFC] children: not-inline
+ Box
at (9,9) content-size 512.859375x19.46875 positioned flex-container(column) [FFC] children: not-inline
+ BlockContainer at (10,10) content-size 510.859375x17.46875 flex-item [BFC] children: inline
+ line 0 width: 510.859375, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+ frag 0 from TextNode start: 0, length: 60, rect: [10,10 510.859375x17.46875]
+ "Diese Website nutzt Cookies und vergleichbare Funktionen zur"
+ TextNode <#text>
diff --git a/Tests/LibWeb/Layout/input/abspos-flex-container-with-auto-height.html b/Tests/LibWeb/Layout/input/abspos-flex-container-with-auto-height.html
new file mode 100644
index 0000000000..f113bd266e
--- /dev/null
+++ b/Tests/LibWeb/Layout/input/abspos-flex-container-with-auto-height.html
@@ -0,0 +1,20 @@
+
Diese Website nutzt Cookies und vergleichbare Funktionen zur
\ No newline at end of file
diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
index f8db4dcc1f..10499dc82f 100644
--- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
@@ -305,6 +305,22 @@ CSSPixelSize FormattingContext::solve_replaced_size_constraint(CSSPixels input_w
return { w, h };
}
+Optional FormattingContext::compute_auto_height_for_absolutely_positioned_element(Box const& box, AvailableSpace const& available_space, BeforeOrAfterInsideLayout before_or_after_inside_layout) const
+{
+ // NOTE: CSS 2.2 tells us to use the "auto height for block formatting context roots" here.
+ // That's fine as long as the box is a BFC root.
+ if (creates_block_formatting_context(box)) {
+ if (before_or_after_inside_layout == BeforeOrAfterInsideLayout::Before)
+ return {};
+ return compute_auto_height_for_block_formatting_context_root(box);
+ }
+
+ // NOTE: For anything else, we use the fit-content height.
+ // This should eventually be replaced by the new absolute positioning model:
+ // https://www.w3.org/TR/css-position-3/#abspos-layout
+ return calculate_fit_content_height(box, available_space);
+}
+
// https://www.w3.org/TR/CSS22/visudet.html#root-height
CSSPixels FormattingContext::compute_auto_height_for_block_formatting_context_root(Box const& root) const
{
@@ -798,10 +814,6 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
// If all three of top, height, and bottom are auto:
if (top.is_auto() && height.is_auto() && bottom.is_auto()) {
- // (If we haven't done inside layout yet, we can't compute the auto height.)
- if (before_or_after_inside_layout == BeforeOrAfterInsideLayout::Before)
- return;
-
// First set any auto values for margin-top and margin-bottom to 0,
if (margin_top.is_auto())
margin_top = CSS::Length::make_px(0);
@@ -813,7 +825,10 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
top = CSS::Length::make_px(static_position.y());
// and finally apply rule number three below.
- height = CSS::Size::make_px(compute_auto_height_for_block_formatting_context_root(box));
+ auto maybe_height = compute_auto_height_for_absolutely_positioned_element(box, available_space, before_or_after_inside_layout);
+ if (!maybe_height.has_value())
+ return;
+ height = CSS::Size::make_px(maybe_height.value());
solve_for_bottom();
}
@@ -853,12 +868,11 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
// 1. If top and height are auto and bottom is not auto,
if (top.is_auto() && height.is_auto() && !bottom.is_auto()) {
- // (If we haven't done inside layout yet, we can't compute the auto height.)
- if (before_or_after_inside_layout == BeforeOrAfterInsideLayout::Before)
- return;
-
// then the height is based on the Auto heights for block formatting context roots,
- height = CSS::Size::make_px(compute_auto_height_for_block_formatting_context_root(box));
+ auto maybe_height = compute_auto_height_for_absolutely_positioned_element(box, available_space, before_or_after_inside_layout);
+ if (!maybe_height.has_value())
+ return;
+ height = CSS::Size::make_px(maybe_height.value());
// and solve for top.
solve_for_top();
@@ -875,12 +889,11 @@ void FormattingContext::compute_height_for_absolutely_positioned_non_replaced_el
// 3. If height and bottom are auto and top is not auto,
else if (height.is_auto() && bottom.is_auto() && !top.is_auto()) {
- // (If we haven't done inside layout yet, we can't compute the auto height.)
- if (before_or_after_inside_layout == BeforeOrAfterInsideLayout::Before)
- return;
-
// then the height is based on the Auto heights for block formatting context roots,
- height = CSS::Size::make_px(compute_auto_height_for_block_formatting_context_root(box));
+ auto maybe_height = compute_auto_height_for_absolutely_positioned_element(box, available_space, before_or_after_inside_layout);
+ if (!maybe_height.has_value())
+ return;
+ height = CSS::Size::make_px(maybe_height.value());
// and solve for bottom.
solve_for_bottom();
diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.h b/Userland/Libraries/LibWeb/Layout/FormattingContext.h
index a220cb1fea..40b1ed1ea6 100644
--- a/Userland/Libraries/LibWeb/Layout/FormattingContext.h
+++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.h
@@ -146,6 +146,8 @@ protected:
void compute_height_for_absolutely_positioned_non_replaced_element(Box const&, AvailableSpace const&, BeforeOrAfterInsideLayout);
void compute_height_for_absolutely_positioned_replaced_element(Box const&, AvailableSpace const&, BeforeOrAfterInsideLayout);
+ [[nodiscard]] Optional compute_auto_height_for_absolutely_positioned_element(Box const&, AvailableSpace const&, BeforeOrAfterInsideLayout) const;
+
Type m_type {};
FormattingContext* m_parent { nullptr };