.item) [264,571.5 30x30]
diff --git a/Tests/LibWeb/Layout/input/grid/align-content.html b/Tests/LibWeb/Layout/input/grid/align-content.html
new file mode 100644
index 00000000000..9903379b6a4
--- /dev/null
+++ b/Tests/LibWeb/Layout/input/grid/align-content.html
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
diff --git a/Userland/Libraries/LibWeb/CSS/Enums.json b/Userland/Libraries/LibWeb/CSS/Enums.json
index 3ab2b0c92e5..5df1b01fbf9 100644
--- a/Userland/Libraries/LibWeb/CSS/Enums.json
+++ b/Userland/Libraries/LibWeb/CSS/Enums.json
@@ -1,7 +1,9 @@
{
"align-content": [
"normal",
+ "start",
"flex-start",
+ "end",
"flex-end",
"center",
"space-between",
diff --git a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
index a98d3d088b0..d966639f60b 100644
--- a/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/FlexFormattingContext.cpp
@@ -1547,9 +1547,11 @@ void FlexFormattingContext::align_all_flex_lines()
CSSPixels gap_size = 0;
switch (flex_container().computed_values().align_content()) {
case CSS::AlignContent::FlexStart:
+ case CSS::AlignContent::Start:
start_of_current_line = 0;
break;
case CSS::AlignContent::FlexEnd:
+ case CSS::AlignContent::End:
start_of_current_line = cross_size_of_flex_container - sum_of_flex_line_cross_sizes;
break;
case CSS::AlignContent::Center:
diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
index 62c8fa78c0d..3f4d6a6d7c6 100644
--- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
+++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp
@@ -1674,34 +1674,31 @@ void GridFormattingContext::resolve_grid_item_heights()
void GridFormattingContext::resolve_track_spacing(GridDimension const dimension)
{
- if (dimension == GridDimension::Column) {
- auto total_gap_space = m_available_space->width.to_px_or_zero();
+ auto is_column_dimension = dimension == GridDimension::Column;
- for (auto& track : m_grid_columns_and_gaps) {
- if (track.is_gap)
- continue;
+ auto total_gap_space = is_column_dimension ? m_available_space->width.to_px_or_zero() : m_available_space->height.to_px_or_zero();
- total_gap_space -= track.base_size;
- }
- total_gap_space = max(total_gap_space, 0);
+ auto& grid_tracks = is_column_dimension ? m_grid_columns : m_grid_rows;
+ for (auto& track : grid_tracks) {
+ total_gap_space -= track.base_size;
+ }
+ total_gap_space = max(total_gap_space, 0);
- auto gap_track_count = m_column_gap_tracks.size();
- if (gap_track_count == 0)
- return;
+ auto gap_track_count = is_column_dimension ? m_column_gap_tracks.size() : m_row_gap_tracks.size();
+ if (gap_track_count == 0)
+ return;
- auto const& gap_space = grid_container().computed_values().column_gap();
- auto const& available_size = m_available_space->width;
-
- CSSPixels space_between_tracks = 0;
+ CSSPixels space_between_tracks = 0;
+ if (is_column_dimension) {
switch (grid_container().computed_values().justify_content()) {
case CSS::JustifyContent::SpaceBetween:
space_between_tracks = CSSPixels(total_gap_space / gap_track_count);
break;
case CSS::JustifyContent::SpaceAround:
- space_between_tracks = CSSPixels(total_gap_space / (m_column_gap_tracks.size() + 1));
+ space_between_tracks = CSSPixels(total_gap_space / (gap_track_count + 1));
break;
case CSS::JustifyContent::SpaceEvenly:
- space_between_tracks = CSSPixels(total_gap_space / (m_grid_columns.size() + 1));
+ space_between_tracks = CSSPixels(total_gap_space / (gap_track_count + 2));
break;
case CSS::JustifyContent::Start:
case CSS::JustifyContent::End:
@@ -1710,17 +1707,36 @@ void GridFormattingContext::resolve_track_spacing(GridDimension const dimension)
default:
break;
}
-
- space_between_tracks = max(space_between_tracks, gap_space.to_px(grid_container(), available_size.to_px_or_zero()));
-
- for (auto& track : m_column_gap_tracks) {
- if (!track.is_gap)
- continue;
-
- track.base_size = space_between_tracks;
- }
} else {
- // TODO: align-content spacing
+ switch (grid_container().computed_values().align_content()) {
+ case CSS::AlignContent::SpaceBetween:
+ space_between_tracks = CSSPixels(total_gap_space / gap_track_count);
+ break;
+ case CSS::AlignContent::SpaceAround:
+ space_between_tracks = CSSPixels(total_gap_space / (gap_track_count + 1));
+ break;
+ case CSS::AlignContent::SpaceEvenly:
+ space_between_tracks = CSSPixels(total_gap_space / (gap_track_count + 2));
+ break;
+ case CSS::AlignContent::Normal:
+ case CSS::AlignContent::Stretch:
+ case CSS::AlignContent::Start:
+ case CSS::AlignContent::FlexStart:
+ case CSS::AlignContent::End:
+ case CSS::AlignContent::FlexEnd:
+ case CSS::AlignContent::Center:
+ default:
+ break;
+ }
+ }
+
+ auto const& computed_gap = is_column_dimension ? grid_container().computed_values().column_gap() : grid_container().computed_values().row_gap();
+ auto const& available_size = is_column_dimension ? m_available_space->width.to_px_or_zero() : m_available_space->height.to_px_or_zero();
+ space_between_tracks = max(space_between_tracks, computed_gap.to_px(grid_container(), available_size));
+
+ auto& gap_tracks = is_column_dimension ? m_column_gap_tracks : m_row_gap_tracks;
+ for (auto& track : gap_tracks) {
+ track.base_size = space_between_tracks;
}
}
@@ -1828,8 +1844,26 @@ CSSPixelRect GridFormattingContext::get_grid_area_rect(GridItem const& grid_item
x_end = gap_space;
}
+ auto grid_container_height = m_available_space->height.to_px_or_zero();
+ CSSPixels sum_base_size_of_rows_and_gaps = 0;
+ for (auto const& row_track : m_grid_rows_and_gaps) {
+ sum_base_size_of_rows_and_gaps += row_track.base_size;
+ }
+ auto const& align_content = grid_container().computed_values().align_content();
+
CSSPixels y_start = 0;
CSSPixels y_end = 0;
+ if (align_content == CSS::AlignContent::Center || align_content == CSS::AlignContent::SpaceAround || align_content == CSS::AlignContent::SpaceEvenly) {
+ auto free_space = grid_container_height - sum_base_size_of_rows_and_gaps;
+ free_space = max(free_space, 0);
+ y_start = free_space / 2;
+ y_end = free_space / 2;
+ } else if (align_content == CSS::AlignContent::End || align_content == CSS::AlignContent::FlexEnd) {
+ auto free_space = grid_container_height - sum_base_size_of_rows_and_gaps;
+ y_start = free_space;
+ y_end = free_space;
+ }
+
for (int i = 0; i < column_start; i++)
x_start += m_grid_columns_and_gaps[i].base_size;
for (int i = 0; i < column_end; i++)
@@ -1914,6 +1948,8 @@ void GridFormattingContext::run(AvailableSpace const& available_space)
resolve_track_spacing(GridDimension::Column);
+ resolve_track_spacing(GridDimension::Row);
+
auto const& containing_block_state = m_state.get(*grid_container().containing_block());
auto height_of_containing_block = containing_block_state.content_height();
auto height_of_container_block_as_available_size = AvailableSize::make_definite(height_of_containing_block);