at (8,16) content-size 1280x600 children: not-inline
+ BlockContainer <(anonymous)> at (8,16) content-size 1280x0 children: inline
+ TextNode <#text>
+ ImageBox
![]()
at (88,16) content-size 1200x600 floating children: not-inline
+ TextNode <#text>
+ BlockContainer
at (8,16) content-size 1280x17.46875 children: inline
+ line 0 width: 37.21875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
+ frag 0 from TextNode start: 0, length: 4, rect: [8,16 37.21875x17.46875]
+ "Test"
+ TextNode <#text>
+ BlockContainer <(anonymous)> at (8,49.46875) content-size 1280x0 children: inline
+ TextNode <#text>
+ BlockContainer <(anonymous)> at (8,616) content-size 1280x0 children: inline
+ TextNode <#text>
+ BlockContainer <(anonymous)> at (8,816) content-size 784x0 children: inline
+ TextNode <#text>
diff --git a/Tests/LibWeb/Layout/input/resolve-height-of-containing-block.html b/Tests/LibWeb/Layout/input/resolve-height-of-containing-block.html
new file mode 100644
index 0000000000..b8aa340683
--- /dev/null
+++ b/Tests/LibWeb/Layout/input/resolve-height-of-containing-block.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+

+
Test
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
index 5682585212..f05884f469 100644
--- a/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/FormattingContext.cpp
@@ -262,7 +262,7 @@ static CSSPixelSize solve_replaced_size_constraint(LayoutState const& state, CSS
{
// 10.4 Minimum and maximum widths: 'min-width' and 'max-width'
- auto const& containing_block = *box.containing_block();
+ auto const& containing_block = *box.non_anyonymous_containing_block();
auto const& containing_block_state = state.get(containing_block);
auto width_of_containing_block = containing_block_state.content_width();
auto height_of_containing_block = containing_block_state.content_height();
@@ -509,7 +509,7 @@ CSSPixels FormattingContext::compute_height_for_replaced_element(LayoutState con
// 10.6.6 Floating replaced elements
// 10.6.10 'inline-block' replaced elements in normal flow
- auto height_of_containing_block = state.get(*box.containing_block()).content_height();
+ auto height_of_containing_block = state.get(*box.non_anyonymous_containing_block()).content_height();
auto computed_width = should_treat_width_as_auto(box, available_space) ? CSS::Size::make_auto() : box.computed_values().width();
auto computed_height = should_treat_height_as_auto(box, available_space) ? CSS::Size::make_auto() : box.computed_values().height();
@@ -1358,7 +1358,7 @@ CSS::Length FormattingContext::calculate_inner_width(Layout::Box const& box, Ava
CSS::Length FormattingContext::calculate_inner_height(Layout::Box const& box, AvailableSize const&, CSS::Size const& height) const
{
- auto height_of_containing_block = m_state.get(*box.containing_block()).content_height();
+ auto height_of_containing_block = m_state.get(*box.non_anyonymous_containing_block()).content_height();
auto height_of_containing_block_as_length_for_resolve = CSS::Length::make_px(height_of_containing_block);
if (height.is_auto()) {
return height.resolved(box, height_of_containing_block_as_length_for_resolve);
diff --git a/Userland/Libraries/LibWeb/Layout/Node.cpp b/Userland/Libraries/LibWeb/Layout/Node.cpp
index 60d4c00485..956e56120f 100644
--- a/Userland/Libraries/LibWeb/Layout/Node.cpp
+++ b/Userland/Libraries/LibWeb/Layout/Node.cpp
@@ -114,6 +114,17 @@ Box const* Node::containing_block() const
return nearest_ancestor_capable_of_forming_a_containing_block(*this);
}
+Box const* Node::non_anyonymous_containing_block() const
+{
+ auto nearest_ancestor_box = containing_block();
+ VERIFY(nearest_ancestor_box);
+ while (nearest_ancestor_box->is_anonymous()) {
+ nearest_ancestor_box = nearest_ancestor_box->containing_block();
+ VERIFY(nearest_ancestor_box);
+ }
+ return nearest_ancestor_box;
+}
+
// https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
bool Node::establishes_stacking_context() const
{
diff --git a/Userland/Libraries/LibWeb/Layout/Node.h b/Userland/Libraries/LibWeb/Layout/Node.h
index 70b1ebd267..0919077882 100644
--- a/Userland/Libraries/LibWeb/Layout/Node.h
+++ b/Userland/Libraries/LibWeb/Layout/Node.h
@@ -112,6 +112,12 @@ public:
Box const* containing_block() const;
Box* containing_block() { return const_cast
(const_cast(this)->containing_block()); }
+ // Closest non-anonymous ancestor box, to be used when resolving percentage values.
+ // Anonymous block boxes are ignored when resolving percentage values that would refer to it:
+ // the closest non-anonymous ancestor box is used instead.
+ // https://www.w3.org/TR/CSS22/visuren.html#anonymous-block-level
+ Box const* non_anyonymous_containing_block() const;
+
bool establishes_stacking_context() const;
bool can_contain_boxes_with_position_absolute() const;