Переглянути джерело

LibWeb: Use the parent container's y offset when finding static position

Fixes #18819.
implicitfield 1 рік тому
батько
коміт
5da9f52b1f

+ 14 - 0
Tests/LibWeb/Layout/expected/abspos-box-with-block-level-sibling.txt

@@ -0,0 +1,14 @@
+Viewport <#document> at (0,0) content-size 800x600 children: not-inline
+  BlockContainer <html> at (5,5) content-size 790x236 [BFC] children: not-inline
+    BlockContainer <body> at (18,18) content-size 764x210 children: not-inline
+      BlockContainer <div.static> at (23,23) content-size 200x200 children: not-inline
+      BlockContainer <div.absolute> at (23,233) content-size 100x200 positioned [BFC] children: not-inline
+      BlockContainer <(anonymous)> at (18,228) content-size 764x0 children: inline
+        TextNode <#text>
+
+ViewportPaintable (Viewport<#document>) [0,0 800x600]
+  PaintableWithLines (BlockContainer<HTML>) [0,0 800x246] overflow: [5,5 790x433]
+    PaintableWithLines (BlockContainer<BODY>) [13,13 774x220] overflow: [18,18 764x420]
+      PaintableWithLines (BlockContainer<DIV>.static) [18,18 210x210]
+      PaintableWithLines (BlockContainer<DIV>.absolute) [18,228 110x210]
+      PaintableWithLines (BlockContainer(anonymous)) [18,228 764x0]

+ 16 - 0
Tests/LibWeb/Layout/input/abspos-box-with-block-level-sibling.html

@@ -0,0 +1,16 @@
+<!DOCTYPE html><style>
+* {
+  border: solid 5px black;
+}
+.static {
+  height: 200px;
+  width: 200px;
+  background: green;
+}
+.absolute {
+  position: absolute;
+  height: 200px;
+  width: 100px;
+  background: blue;
+}
+</style><div class="static"></div><div class="absolute"></div></div>

+ 1 - 0
Userland/Libraries/LibWeb/Layout/BlockFormattingContext.cpp

@@ -585,6 +585,7 @@ void BlockFormattingContext::layout_block_level_box(Box const& box, BlockContain
     auto& box_state = m_state.get_mutable(box);
     auto& box_state = m_state.get_mutable(box);
 
 
     if (box.is_absolutely_positioned()) {
     if (box.is_absolutely_positioned()) {
+        box_state.vertical_offset_of_parent_block_container = m_y_offset_of_current_block_container.value();
         m_absolutely_positioned_boxes.append(box);
         m_absolutely_positioned_boxes.append(box);
         return;
         return;
     }
     }

+ 3 - 2
Userland/Libraries/LibWeb/Layout/FormattingContext.cpp

@@ -1204,9 +1204,10 @@ CSSPixelPoint FormattingContext::calculate_static_position(Box const& box) const
             // Easy case: no previous sibling, we're at the top of the containing block.
             // Easy case: no previous sibling, we're at the top of the containing block.
         }
         }
     } else {
     } else {
-        x = m_state.get(box).margin_left;
+        auto const& box_state = m_state.get(box);
+        x = box_state.margin_left;
         // We're among block siblings, Y can be calculated easily.
         // We're among block siblings, Y can be calculated easily.
-        y = m_state.get(box).margin_top;
+        y = box_state.margin_top + box_state.vertical_offset_of_parent_block_container;
     }
     }
     auto offset_to_static_parent = content_box_rect_in_static_position_ancestor_coordinate_space(box, *box.containing_block());
     auto offset_to_static_parent = content_box_rect_in_static_position_ancestor_coordinate_space(box, *box.containing_block());
     return offset_to_static_parent.location().translated(x, y);
     return offset_to_static_parent.location().translated(x, y);

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

@@ -100,6 +100,9 @@ struct LayoutState {
         CSSPixels inset_top { 0 };
         CSSPixels inset_top { 0 };
         CSSPixels inset_bottom { 0 };
         CSSPixels inset_bottom { 0 };
 
 
+        // Used for calculating the static position of an abspos block-level box.
+        CSSPixels vertical_offset_of_parent_block_container { 0 };
+
         Vector<LineBox> line_boxes;
         Vector<LineBox> line_boxes;
 
 
         CSSPixels margin_box_left() const { return margin_left + border_left_collapsed() + padding_left; }
         CSSPixels margin_box_left() const { return margin_left + border_left_collapsed() + padding_left; }