.abspos-item) [111,11 52x52]
diff --git a/Tests/LibWeb/Layout/input/grid/abspos-item-with-grid-area.html b/Tests/LibWeb/Layout/input/grid/abspos-item-with-grid-area.html
new file mode 100644
index 0000000000..af26423b6c
--- /dev/null
+++ b/Tests/LibWeb/Layout/input/grid/abspos-item-with-grid-area.html
@@ -0,0 +1,23 @@
+
\ No newline at end of file
diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
index 3392e6dc11..7a96b9735f 100644
--- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
@@ -1958,6 +1958,56 @@ void GridFormattingContext::layout_absolutely_positioned_element(Box const& box,
auto& box_state = m_state.get_mutable(box);
auto const& computed_values = box.computed_values();
+ auto const& grid_row_start = computed_values.grid_row_start();
+ auto const& grid_row_end = computed_values.grid_row_end();
+ auto const& grid_column_start = computed_values.grid_column_start();
+ auto const& grid_column_end = computed_values.grid_column_end();
+
+ int row_start = 0, row_end = 0, column_start = 0, column_end = 0;
+
+ if (grid_column_end.has_identifier()) {
+ if (auto maybe_grid_area = m_grid_areas.get(grid_column_end.identifier()); maybe_grid_area.has_value())
+ column_end = maybe_grid_area->column_end;
+ else if (auto line_name_index = get_line_index_by_line_name(grid_column_end.identifier(), grid_container().computed_values().grid_template_columns()); line_name_index > -1)
+ column_end = line_name_index;
+ else
+ column_end = 1;
+ column_start = column_end - 1;
+ }
+
+ if (grid_column_start.has_identifier()) {
+ if (auto maybe_grid_area = m_grid_areas.get(grid_column_start.identifier()); maybe_grid_area.has_value())
+ column_start = maybe_grid_area->column_start;
+ else if (auto line_name_index = get_line_index_by_line_name(grid_column_start.identifier(), grid_container().computed_values().grid_template_columns()); line_name_index > -1)
+ column_start = line_name_index;
+ else
+ column_start = 0;
+ }
+
+ if (grid_row_end.has_identifier()) {
+ if (auto maybe_grid_area = m_grid_areas.get(grid_row_end.identifier()); maybe_grid_area.has_value())
+ row_end = maybe_grid_area->row_end;
+ else if (auto line_name_index = get_line_index_by_line_name(grid_row_end.identifier(), grid_container().computed_values().grid_template_rows()); line_name_index > -1)
+ row_end = line_name_index;
+ else
+ row_end = 1;
+ row_start = row_end - 1;
+ }
+
+ if (grid_row_start.has_identifier()) {
+ if (auto maybe_grid_area = m_grid_areas.get(grid_row_start.identifier()); maybe_grid_area.has_value())
+ row_start = maybe_grid_area->row_start;
+ else if (auto line_name_index = get_line_index_by_line_name(grid_row_start.identifier(), grid_container().computed_values().grid_template_rows()); line_name_index > -1)
+ row_start = line_name_index;
+ else
+ row_start = 0;
+ }
+
+ size_t row_span = row_end - row_start;
+ size_t column_span = column_end - column_start;
+
+ GridItem item { box, row_start, row_span, column_start, column_span };
+
// The border computed values are not changed by the compute_height & width calculations below.
// The spec only adjusts and computes sizes, insets and margins.
box_state.border_left = box.computed_values().border_left().width;
@@ -2029,9 +2079,14 @@ void GridFormattingContext::layout_absolutely_positioned_element(Box const& box,
}
}
+ // If an absolutely positioned element’s containing block is generated by a grid container,
+ // the containing block corresponds to the grid area determined by its grid-placement properties.
+ // The offset properties (top/right/bottom/left) then indicate offsets inwards from the corresponding
+ // edges of this containing block, as normal.
CSSPixelPoint used_offset;
- used_offset.set_x(box_state.inset_left + box_state.margin_box_left());
- used_offset.set_y(box_state.inset_top + box_state.margin_box_top());
+ auto grid_area_offset = get_grid_area_rect(item);
+ used_offset.set_x(grid_area_offset.x() + box_state.inset_left + box_state.margin_box_left());
+ used_offset.set_y(grid_area_offset.y() + box_state.inset_top + box_state.margin_box_top());
// NOTE: Absolutely positioned boxes are relative to the *padding edge* of the containing block.
used_offset.translate_by(-containing_block_state.padding_left, -containing_block_state.padding_top);