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 };