From 03611982ffba880cf5645d76d34ea5c7c5b5680d Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 8 Oct 2026 18:18:43 +0000 Subject: [PATCH 1/2] =?UTF-8?q?Grid=20Lanes:=20stacking-axis=20content=20d?= =?UTF-8?q?istribution=20and=20self-alignment=20(spec=20=C2=A76.3/=C2=A76.?= =?UTF-8?q?4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 2 +- src/compute/grid/lanes.rs | 171 +++++++-- .../grid_lanes_align_content_center.html | 20 ++ .../grid_lanes_align_content_end.html | 20 ++ .../grid_lanes_align_content_safe_end.html | 20 ++ ...grid_lanes_align_content_space_around.html | 20 ++ .../grid_lanes_align_items_center.html | 21 ++ .../grid_lanes_align_items_end.html | 21 ++ .../grid_lanes_align_items_gap.html | 21 ++ .../grid_lanes_align_items_normal.html | 22 ++ .../grid_lanes_align_items_rtl.html | 21 ++ .../grid_lanes_align_items_stretch.html | 22 ++ .../grid_lanes_align_self_mixed.html | 21 ++ .../grid_lanes_dense_align_items_end.html | 22 ++ ...grid_lanes_justify_content_center_row.html | 20 ++ .../grid_lanes_justify_items_end_row.html | 21 ++ ...s_align_content_center__border_box_ltr.xml | 19 + ...s_align_content_center__border_box_rtl.xml | 19 + ..._align_content_center__content_box_ltr.xml | 19 + ..._align_content_center__content_box_rtl.xml | 19 + ...anes_align_content_end__border_box_ltr.xml | 19 + ...anes_align_content_end__border_box_rtl.xml | 19 + ...nes_align_content_end__content_box_ltr.xml | 19 + ...nes_align_content_end__content_box_rtl.xml | 19 + ...align_content_safe_end__border_box_ltr.xml | 19 + ...align_content_safe_end__border_box_rtl.xml | 19 + ...lign_content_safe_end__content_box_ltr.xml | 19 + ...lign_content_safe_end__content_box_rtl.xml | 19 + ...n_content_space_around__border_box_ltr.xml | 19 + ...n_content_space_around__border_box_rtl.xml | 19 + ..._content_space_around__content_box_ltr.xml | 19 + ..._content_space_around__content_box_rtl.xml | 19 + ...nes_align_items_center__border_box_ltr.xml | 21 ++ ...nes_align_items_center__border_box_rtl.xml | 21 ++ ...es_align_items_center__content_box_ltr.xml | 21 ++ ...es_align_items_center__content_box_rtl.xml | 21 ++ ..._lanes_align_items_end__border_box_ltr.xml | 21 ++ ..._lanes_align_items_end__border_box_rtl.xml | 21 ++ ...lanes_align_items_end__content_box_ltr.xml | 21 ++ ...lanes_align_items_end__content_box_rtl.xml | 21 ++ ..._lanes_align_items_gap__border_box_ltr.xml | 21 ++ ..._lanes_align_items_gap__border_box_rtl.xml | 21 ++ ...lanes_align_items_gap__content_box_ltr.xml | 21 ++ ...lanes_align_items_gap__content_box_rtl.xml | 21 ++ ...nes_align_items_normal__border_box_ltr.xml | 23 ++ ...nes_align_items_normal__border_box_rtl.xml | 23 ++ ...es_align_items_normal__content_box_ltr.xml | 23 ++ ...es_align_items_normal__content_box_rtl.xml | 23 ++ ..._lanes_align_items_rtl__border_box_ltr.xml | 21 ++ ..._lanes_align_items_rtl__border_box_rtl.xml | 21 ++ ...lanes_align_items_rtl__content_box_ltr.xml | 21 ++ ...lanes_align_items_rtl__content_box_rtl.xml | 21 ++ ...es_align_items_stretch__border_box_ltr.xml | 23 ++ ...es_align_items_stretch__border_box_rtl.xml | 23 ++ ...s_align_items_stretch__content_box_ltr.xml | 23 ++ ...s_align_items_stretch__content_box_rtl.xml | 23 ++ ...lanes_align_self_mixed__border_box_ltr.xml | 21 ++ ...lanes_align_self_mixed__border_box_rtl.xml | 21 ++ ...anes_align_self_mixed__content_box_ltr.xml | 21 ++ ...anes_align_self_mixed__content_box_rtl.xml | 21 ++ ..._dense_align_items_end__border_box_ltr.xml | 23 ++ ..._dense_align_items_end__border_box_rtl.xml | 23 ++ ...dense_align_items_end__content_box_ltr.xml | 23 ++ ...dense_align_items_end__content_box_rtl.xml | 23 ++ ...ify_content_center_row__border_box_ltr.xml | 19 + ...ify_content_center_row__border_box_rtl.xml | 19 + ...fy_content_center_row__content_box_ltr.xml | 19 + ...fy_content_center_row__content_box_rtl.xml | 19 + ..._justify_items_end_row__border_box_ltr.xml | 21 ++ ..._justify_items_end_row__border_box_rtl.xml | 21 ++ ...justify_items_end_row__content_box_ltr.xml | 21 ++ ...justify_items_end_row__content_box_rtl.xml | 21 ++ tests/xml/mod.rs | 336 ++++++++++++++++++ 73 files changed, 1926 insertions(+), 35 deletions(-) create mode 100644 test_fixtures/grid_lanes/grid_lanes_align_content_center.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_align_content_end.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_align_content_safe_end.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_align_content_space_around.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_align_items_center.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_align_items_end.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_align_items_gap.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_align_items_normal.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_align_items_rtl.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_align_items_stretch.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_align_self_mixed.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_dense_align_items_end.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_justify_content_center_row.html create mode 100644 test_fixtures/grid_lanes/grid_lanes_justify_items_end_row.html create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_center__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_center__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_center__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_center__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_end__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_end__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_end__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_end__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_safe_end__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_safe_end__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_safe_end__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_safe_end__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_space_around__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_space_around__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_space_around__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_content_space_around__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_center__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_center__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_center__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_center__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_end__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_end__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_end__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_end__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_gap__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_gap__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_gap__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_gap__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_normal__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_normal__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_normal__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_normal__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_rtl__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_rtl__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_rtl__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_rtl__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_stretch__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_stretch__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_stretch__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_items_stretch__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_self_mixed__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_self_mixed__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_self_mixed__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_align_self_mixed__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_dense_align_items_end__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_dense_align_items_end__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_dense_align_items_end__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_dense_align_items_end__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_justify_content_center_row__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_justify_content_center_row__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_justify_content_center_row__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_justify_content_center_row__content_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_justify_items_end_row__border_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_justify_items_end_row__border_box_rtl.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_justify_items_end_row__content_box_ltr.xml create mode 100644 tests/xml/grid_lanes/grid_lanes_justify_items_end_row__content_box_rtl.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index fa5354a69..372def0d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,7 +60,7 @@ ### Added -- Initial support for CSS Grid Level 3 [Grid Lanes](https://drafts.csswg.org/css-grid-3/) behind the new `grid_lanes` feature (#1270). `Display::GridLanes` lays items out in a waterfall along the stacking axis of a container whose tracks are defined in the other axis (`GridLanesDirection`; `Style::grid_lanes_direction` / `GridContainerStyle::grid_lanes_direction()`), with the auto-placement tie threshold set by `Style::fit_tolerance` / `GridContainerStyle::fit_tolerance()` (a `LengthPercentage`; `infinite` is `LengthPercentage::length(f32::INFINITY)`). The new trait getters have default implementations. Auto-placed items contribute to intrinsic grid-axis track sizes through the spec's virtual-item optimization (#1272). Containers whose `grid_auto_flow` is dense backfill items into skipped spaces (#1274). Stacking-axis alignment and absolutely positioned children follow in later releases +- Initial support for CSS Grid Level 3 [Grid Lanes](https://drafts.csswg.org/css-grid-3/) behind the new `grid_lanes` feature (#1270). `Display::GridLanes` lays items out in a waterfall along the stacking axis of a container whose tracks are defined in the other axis (`GridLanesDirection`; `Style::grid_lanes_direction` / `GridContainerStyle::grid_lanes_direction()`), with the auto-placement tie threshold set by `Style::fit_tolerance` / `GridContainerStyle::fit_tolerance()` (a `LengthPercentage`; `infinite` is `LengthPercentage::length(f32::INFINITY)`). The new trait getters have default implementations. Auto-placed items contribute to intrinsic grid-axis track sizes through the spec's virtual-item optimization (#1272). Containers whose `grid_auto_flow` is dense backfill items into skipped spaces (#1274). `align_content`/`justify_content` in the stacking axis moves the stacking range as a whole, and items adjacent to a gap (the last item in a track, or one followed by a spanning item) align within their margin box plus that gap with `align_self`/`justify_self`; baseline alignment in the stacking axis falls back to `start` (#TODO). Absolutely positioned children follow in a later release - `CoreStyle::is_replaced()` (defaulting to `false`; `Style::item_is_replaced`) now identifies [replaced elements](https://html.spec.whatwg.org/multipage/rendering.html#replaced-elements) for absolute positioning: only these (and tables) are exempt from being stretched between their insets under `normal` alignment. `CoreStyle::is_compressible_replaced()` now has its css-sizing meaning of [compressible replaced element](https://drafts.csswg.org/css-sizing-3/#compressible) — replaced elements *plus* form controls with an intrinsic size (`input`, `select`, `textarea`, `progress`, `meter`) — and is what block layout consults when deciding that an auto-width block-level box takes its intrinsic width rather than being stretched (matching browsers, where a block-level `` keeps its intrinsic width but a `position: absolute; left: 0; right: 0` one is stretched). `Style` gains `item_is_compressible_replaced` for the form-control case; `item_is_replaced: true` continues to imply both. - `AlignSelf::is_stretch_or_normal` returns whether an alignment's keyword is `Stretch` or `Normal` - `AlignItems`, `AlignItemsKeyword` and `AlignmentSafety` now implement `Default` (`AlignItems::NORMAL`, `AlignItemsKeyword::Normal` and `AlignmentSafety::Default`) diff --git a/src/compute/grid/lanes.rs b/src/compute/grid/lanes.rs index 85c09ef2b..86aec7a2b 100644 --- a/src/compute/grid/lanes.rs +++ b/src/compute/grid/lanes.rs @@ -4,8 +4,7 @@ //! "stacking axis") by placing each one into the shortest run of tracks it can span. //! Shares the explicit-grid, track-sizing and item-positioning machinery of [`super::compute_grid_layout`]. //! -//! Current limitations: no dense packing (§4.3), no stacking-axis alignment other than start (§6.3/§6.4), no baselines -//! (§6.5) and no detailed layout info. +//! Current limitations: no stacking-axis baselines (§6.5) and no detailed layout info. use super::alignment::{align_and_position_item, align_tracks}; use super::explicit_grid::{compute_explicit_grid_size_in_axis, initialize_grid_tracks, AutoRepeatStrategy}; use super::placement::ItemPlacement; @@ -23,8 +22,9 @@ use crate::tree::{ use crate::util::sys::{f32_max, f32_min, GridTrackVec, Vec}; use crate::util::{MaybeMath, MaybeResolve, ResolveOrZero}; use crate::{ - style_helpers::*, BoxGenerationMode, BoxSizing, CoreStyle, GridContainerStyle, GridItemStyle, LayoutGridContainer, - LengthPercentage, MaxTrackSizingFunction, MinTrackSizingFunction, Overflow, RequestedAxis, + style_helpers::*, AlignContentKeyword, AlignItems, AlignItemsKeyword, AlignmentSafety, BoxGenerationMode, + BoxSizing, CoreStyle, GridContainerStyle, GridItemStyle, LayoutGridContainer, LengthPercentage, + MaxTrackSizingFunction, MinTrackSizingFunction, Overflow, RequestedAxis, }; /// Where an item ended up in the grid axis and the stacking axis @@ -38,6 +38,9 @@ struct LanePlacement { position: f32, /// Stacking-axis size of the item's margin box (floored at zero) outer_size: f32, + /// Free space after the item's margin box and gutter, up to the next item in every spanned track or the content + /// box end: the stacking-axis alignment container minus the alignment subject (spec §6.4). Infinite until known. + alignment_space: f32, } /// The abstract axis corresponding to an absolute axis (horizontal writing mode) @@ -94,11 +97,20 @@ fn set_item_grid_axis_lines( } } +/// A skipped space in a track and the item placed directly before it, which may align into it (spec §6.4) +#[derive(Clone, Copy)] +struct Opening { + /// Stacking-axis range of the skipped space + range: Line, + /// Index of the item placed directly before the space, if it was placed by normal placement or backfilling + item_above: Option, +} + /// The stacking-axis ranges of a track an item can be backfilled into when `dense` packing is on (spec §4.3). /// The bounded ranges are skipped spaces; the open end of the track starts at its running position. struct TrackOpenings { /// Bounded skipped spaces, in stacking-axis order - skipped: Vec>, + skipped: Vec, /// Start of the open end of the track (the track's running position) running_position: f32, } @@ -106,40 +118,50 @@ struct TrackOpenings { impl TrackOpenings { /// All openings of the track, the unbounded open end last fn skipped_and_open_end(&self) -> impl Iterator> + '_ { - self.skipped.iter().copied().chain(core::iter::once(Line { start: self.running_position, end: f32::INFINITY })) + self.skipped + .iter() + .map(|opening| opening.range) + .chain(core::iter::once(Line { start: self.running_position, end: f32::INFINITY })) } /// Record the skipped space between the track's running position and `position` (if any) and advance the track - fn place(&mut self, position: f32, new_running_position: f32) { + fn place(&mut self, position: f32, new_running_position: f32, item_above: Option) { if self.running_position < position { - self.skipped.push(Line { start: self.running_position, end: position }); + self.skipped.push(Opening { range: Line { start: self.running_position, end: position }, item_above }); } self.running_position = new_running_position; } - /// Carve the range `start..start + extent` out of the opening that contains it - fn occupy(&mut self, start: f32, extent: f32) { + /// Carve the range `start..start + extent` of item `item` out of the opening that contains it. For a skipped space, + /// returns the item placed before it and the end of the remaining space below the item (`None` if it fills it). + fn occupy(&mut self, start: f32, extent: f32, item: usize) -> Option<(Option, Option)> { let end = start + extent; - match self.skipped.iter().position(|opening| opening.start <= start && end <= opening.end) { + match self.skipped.iter().position(|opening| opening.range.start <= start && end <= opening.range.end) { Some(index) => { let opening = self.skipped[index]; - if opening.start < start { - self.skipped[index].end = start; - if end < opening.end { - self.skipped.insert(index + 1, Line { start: end, end: opening.end }); + let below = (end < opening.range.end).then_some(opening.range.end); + if opening.range.start < start { + self.skipped[index].range.end = start; + if let Some(below_end) = below { + let range = Line { start: end, end: below_end }; + self.skipped.insert(index + 1, Opening { range, item_above: Some(item) }); } - } else if end < opening.end { - self.skipped[index].start = end; + } else if below.is_some() { + self.skipped[index].range.start = end; + self.skipped[index].item_above = Some(item); } else { self.skipped.remove(index); } + Some((opening.item_above, below)) } None => { debug_assert!(self.running_position <= start); if self.running_position < start { - self.skipped.push(Line { start: self.running_position, end: start }); + let range = Line { start: self.running_position, end: start }; + self.skipped.push(Opening { range, item_above: None }); } self.running_position = end; + None } } } @@ -206,6 +228,21 @@ fn find_dense_placement( ) } +/// An item placed at `position` in `track` bounds the stacking-axis alignment container of the item placed before it +fn close_alignment_space( + lane_placements: &mut [LanePlacement], + last_in_track: &[Option], + track: usize, + position: f32, + stacking_gap: f32, +) { + if let Some(previous) = last_in_track[track] { + let previous = &mut lane_placements[previous]; + let space = position - stacking_gap - (previous.position + previous.outer_size); + previous.alignment_space = f32_min(previous.alignment_space, space); + } +} + /// The largest grid-axis size contributions (margins included) of the auto-placed items sharing a span. /// One virtual item per possible start line stands in for the group during track sizing (spec §3.4.2). struct ItemGroup { @@ -735,7 +772,13 @@ pub fn compute_grid_lanes_layout( let mut cursor: usize = 0; let mut stacking_range_end: f32 = 0.0; let mut lane_placements: Vec = Vec::with_capacity(items.len()); - lane_placements.resize(items.len(), LanePlacement { start_track: 0, span: 0, position: 0.0, outer_size: 0.0 }); + lane_placements.resize( + items.len(), + LanePlacement { start_track: 0, span: 0, position: 0.0, outer_size: 0.0, alignment_space: f32::INFINITY }, + ); + // The item placed last in each track so far: the one that may align into the space after it (spec §6.4) + let mut last_in_track: Vec> = Vec::with_capacity(track_count); + last_in_track.resize(track_count, None); // Items are placed in document order (the definite-first order of `items` only serves track sizing) let mut document_order: Vec = (0..items.len()).collect(); document_order.sort_unstable_by_key(|&index| items[index].source_order); @@ -786,14 +829,36 @@ pub fn compute_grid_lanes_layout( } else { None }; + let mut alignment_space = f32::INFINITY; match backfill { Some((dense_start, dense_position)) => { if dense_start != start_track { set_item_grid_axis_lines(item, grid_axis, g_counts, dense_start, span); } - openings[dense_start..dense_start + span] - .iter_mut() - .for_each(|track| track.occupy(dense_position, extent)); + for track in dense_start..dense_start + span { + match openings[track].occupy(dense_position, extent, index) { + // The item before the skipped space now aligns only up to this item + Some((item_above, below_end)) => { + if let Some(above) = item_above { + let above = &mut lane_placements[above]; + let space = dense_position - stacking_gap - (above.position + above.outer_size); + above.alignment_space = f32_min(above.alignment_space, space); + } + let space = below_end.map_or(0.0, |end| end - stacking_gap - (dense_position + outer_size)); + alignment_space = f32_min(alignment_space, space); + } + None => { + close_alignment_space( + &mut lane_placements, + &last_in_track, + track, + dense_position, + stacking_gap, + ); + last_in_track[track] = Some(index); + } + } + } start_track = dense_start; position = dense_position; } @@ -802,16 +867,18 @@ pub fn compute_grid_lanes_layout( cursor = start_track + span; } let new_position = position + extent; - running_positions[start_track..start_track + span].iter_mut().for_each(|pos| *pos = new_position); - if dense { - openings[start_track..start_track + span] - .iter_mut() - .for_each(|track| track.place(position, new_position)); + for track in start_track..start_track + span { + close_alignment_space(&mut lane_placements, &last_in_track, track, position, stacking_gap); + if dense { + openings[track].place(position, new_position, last_in_track[track]); + } + last_in_track[track] = Some(index); + running_positions[track] = new_position; } } } stacking_range_end = f32_max(stacking_range_end, position + outer_size); - lane_placements[index] = LanePlacement { start_track, span, position, outer_size }; + lane_placements[index] = LanePlacement { start_track, span, position, outer_size, alignment_space }; } drop(openings); drop(document_order); @@ -830,6 +897,26 @@ pub fn compute_grid_lanes_layout( } let s_content_box = f32_max(0.0, s_border_box - axis_sum(content_box_inset, stacking_axis)); inner_node_size.set(s_axis, Some(s_content_box)); + // The last item in each track may align into the space up to the content box end (spec §6.4) + for item_index in last_in_track.into_iter().flatten() { + let lane = &mut lane_placements[item_index]; + lane.alignment_space = f32_min(lane.alignment_space, s_content_box - (lane.position + lane.outer_size)); + } + // Content distribution moves the stacking range as a whole (spec §6.3) + let s_free_space = s_content_box - stacking_range_end; + let s_free_space = + if s_align_content.safety == AlignmentSafety::Safe { f32_max(0.0, s_free_space) } else { s_free_space }; + let s_content_offset = match s_align_content.keyword { + AlignContentKeyword::Center | AlignContentKeyword::SpaceAround | AlignContentKeyword::SpaceEvenly => { + s_free_space / 2.0 + } + AlignContentKeyword::End | AlignContentKeyword::FlexEnd => s_free_space, + AlignContentKeyword::Normal + | AlignContentKeyword::Start + | AlignContentKeyword::FlexStart + | AlignContentKeyword::Stretch + | AlignContentKeyword::SpaceBetween => 0.0, + }; // 9. Align the grid-axis tracks and position the items let inline_size_without_scrollbar = f32_max(container_border_box.width - padding_border_size.width, 0.0); @@ -858,17 +945,31 @@ pub fn compute_grid_lanes_layout( // Items stack from the content box's start edge; a horizontal stacking axis follows the container's direction let stacking_reversed = stacking_axis == AbsoluteAxis::Horizontal && direction.is_rtl(); let stacking_origin = match stacking_axis { - AbsoluteAxis::Vertical => border.top + padding.top, + AbsoluteAxis::Vertical => border.top + padding.top + s_content_offset, AbsoluteAxis::Horizontal if stacking_reversed => { - container_border_box.width - border.right - padding.right - inline_scrollbar_gutter_for_alignment + container_border_box.width + - border.right + - padding.right + - inline_scrollbar_gutter_for_alignment + - s_content_offset } - AbsoluteAxis::Horizontal => border.left + padding.left, + AbsoluteAxis::Horizontal => border.left + padding.left + s_content_offset, }; #[cfg_attr(not(feature = "content_size"), allow(unused_mut))] let mut item_overflow_rect = Rect::ZERO; let mut oof_candidates = OofCandidates::new(); - let container_alignment_styles = InBothAbsAxis { horizontal: justify_items, vertical: align_items }; + // `normal` self-alignment behaves as `start` in the stacking axis (spec §6.4), not as `stretch` + let s_align_items = match stacking_axis { + AbsoluteAxis::Horizontal => justify_items, + AbsoluteAxis::Vertical => align_items, + }; + let s_align_items = + if s_align_items.keyword == AlignItemsKeyword::Normal { AlignItems::START } else { s_align_items }; + let container_alignment_styles = match stacking_axis { + AbsoluteAxis::Horizontal => InBothAbsAxis { horizontal: s_align_items, vertical: align_items }, + AbsoluteAxis::Vertical => InBothAbsAxis { horizontal: justify_items, vertical: s_align_items }, + }; for (index, (item, lane)) in items.iter_mut().zip(lane_placements.iter()).enumerate() { let start_index = 2 * lane.start_track; let end_index = 2 * (lane.start_track + lane.span); @@ -877,10 +978,12 @@ pub fn compute_grid_lanes_layout( } else { Line { start: g_tracks[start_index + 1].offset, end: g_tracks[end_index].offset } }; + // The stacking-axis alignment container is the item's margin box plus the free space after it (spec §6.4) + let s_extent = lane.outer_size + f32_max(0.0, lane.alignment_space); let s_area = if stacking_reversed { - Line { start: stacking_origin - lane.position - lane.outer_size, end: stacking_origin - lane.position } + Line { start: stacking_origin - lane.position - s_extent, end: stacking_origin - lane.position } } else { - Line { start: stacking_origin + lane.position, end: stacking_origin + lane.position + lane.outer_size } + Line { start: stacking_origin + lane.position, end: stacking_origin + lane.position + s_extent } }; // The item's containing block is its grid area in the grid axis and the container's content box in the stacking axis let mut containing_block_size = Size::ZERO; diff --git a/test_fixtures/grid_lanes/grid_lanes_align_content_center.html b/test_fixtures/grid_lanes/grid_lanes_align_content_center.html new file mode 100644 index 000000000..493708278 --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_align_content_center.html @@ -0,0 +1,20 @@ + + + + + + + Grid Lanes: align-content centers the stacking range + + + + +
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_align_content_end.html b/test_fixtures/grid_lanes/grid_lanes_align_content_end.html new file mode 100644 index 000000000..cc57ea1aa --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_align_content_end.html @@ -0,0 +1,20 @@ + + + + + + + Grid Lanes: align-content end shifts the stacking range to the end edge + + + + +
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_align_content_safe_end.html b/test_fixtures/grid_lanes/grid_lanes_align_content_safe_end.html new file mode 100644 index 000000000..777bade6b --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_align_content_safe_end.html @@ -0,0 +1,20 @@ + + + + + + + Grid Lanes: safe end alignment falls back to start when the stacking range overflows + + + + +
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_align_content_space_around.html b/test_fixtures/grid_lanes/grid_lanes_align_content_space_around.html new file mode 100644 index 000000000..a020c3100 --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_align_content_space_around.html @@ -0,0 +1,20 @@ + + + + + + + Grid Lanes: distributed content alignment falls back in the stacking axis + + + + +
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_align_items_center.html b/test_fixtures/grid_lanes/grid_lanes_align_items_center.html new file mode 100644 index 000000000..e9101c051 --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_align_items_center.html @@ -0,0 +1,21 @@ + + + + + + + Grid Lanes: align-items center within the gap below the last items in each track + + + + +
+
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_align_items_end.html b/test_fixtures/grid_lanes/grid_lanes_align_items_end.html new file mode 100644 index 000000000..ec639ff27 --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_align_items_end.html @@ -0,0 +1,21 @@ + + + + + + + Grid Lanes: align-items end moves items next to a gap to the end of the gap + + + + +
+
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_align_items_gap.html b/test_fixtures/grid_lanes/grid_lanes_align_items_gap.html new file mode 100644 index 000000000..60432f72b --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_align_items_gap.html @@ -0,0 +1,21 @@ + + + + + + + Grid Lanes: the stacking-axis gutter is excluded from the alignment container + + + + +
+
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_align_items_normal.html b/test_fixtures/grid_lanes/grid_lanes_align_items_normal.html new file mode 100644 index 000000000..c89c6f29f --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_align_items_normal.html @@ -0,0 +1,22 @@ + + + + + + + Grid Lanes: normal alignment stretches auto-height items into the adjacent gap + + + + +
+
+
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_align_items_rtl.html b/test_fixtures/grid_lanes/grid_lanes_align_items_rtl.html new file mode 100644 index 000000000..f89383980 --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_align_items_rtl.html @@ -0,0 +1,21 @@ + + + + + + + Grid Lanes: justify-items end in a row-direction rtl container + + + + +
+
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_align_items_stretch.html b/test_fixtures/grid_lanes/grid_lanes_align_items_stretch.html new file mode 100644 index 000000000..aa7b71bec --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_align_items_stretch.html @@ -0,0 +1,22 @@ + + + + + + + Grid Lanes: align-items stretch grows auto-height items into the adjacent gap + + + + +
+
+
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_align_self_mixed.html b/test_fixtures/grid_lanes/grid_lanes_align_self_mixed.html new file mode 100644 index 000000000..d0678cb7c --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_align_self_mixed.html @@ -0,0 +1,21 @@ + + + + + + + Grid Lanes: align-self overrides align-items per item in the stacking axis + + + + +
+
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_dense_align_items_end.html b/test_fixtures/grid_lanes/grid_lanes_dense_align_items_end.html new file mode 100644 index 000000000..b5743666b --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_dense_align_items_end.html @@ -0,0 +1,22 @@ + + + + + + + Grid Lanes: dense-packed items take part in stacking-axis alignment + + + + +
+
+
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_justify_content_center_row.html b/test_fixtures/grid_lanes/grid_lanes_justify_content_center_row.html new file mode 100644 index 000000000..b698c84af --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_justify_content_center_row.html @@ -0,0 +1,20 @@ + + + + + + + Grid Lanes: justify-content centers the stacking range in a row-direction container + + + + +
+
+
+
+
+
+ + + diff --git a/test_fixtures/grid_lanes/grid_lanes_justify_items_end_row.html b/test_fixtures/grid_lanes/grid_lanes_justify_items_end_row.html new file mode 100644 index 000000000..c5a1dbebd --- /dev/null +++ b/test_fixtures/grid_lanes/grid_lanes_justify_items_end_row.html @@ -0,0 +1,21 @@ + + + + + + + Grid Lanes: justify-items end in a row-direction container + + + + +
+
+
+
+
+
+
+ + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_center__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_content_center__border_box_ltr.xml new file mode 100644 index 000000000..84abbcbe0 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_center__border_box_ltr.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_center__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_content_center__border_box_rtl.xml new file mode 100644 index 000000000..820f979b8 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_center__border_box_rtl.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_center__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_content_center__content_box_ltr.xml new file mode 100644 index 000000000..b49806674 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_center__content_box_ltr.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_center__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_content_center__content_box_rtl.xml new file mode 100644 index 000000000..14e14880b --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_center__content_box_rtl.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_end__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_content_end__border_box_ltr.xml new file mode 100644 index 000000000..d1f432af2 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_end__border_box_ltr.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_end__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_content_end__border_box_rtl.xml new file mode 100644 index 000000000..b0a605e0e --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_end__border_box_rtl.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_end__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_content_end__content_box_ltr.xml new file mode 100644 index 000000000..048ee910a --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_end__content_box_ltr.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_end__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_content_end__content_box_rtl.xml new file mode 100644 index 000000000..04ed0d9be --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_end__content_box_rtl.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_safe_end__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_content_safe_end__border_box_ltr.xml new file mode 100644 index 000000000..398c89fde --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_safe_end__border_box_ltr.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_safe_end__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_content_safe_end__border_box_rtl.xml new file mode 100644 index 000000000..496faa019 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_safe_end__border_box_rtl.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_safe_end__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_content_safe_end__content_box_ltr.xml new file mode 100644 index 000000000..d28219310 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_safe_end__content_box_ltr.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_safe_end__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_content_safe_end__content_box_rtl.xml new file mode 100644 index 000000000..cdd94ef9d --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_safe_end__content_box_rtl.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_space_around__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_content_space_around__border_box_ltr.xml new file mode 100644 index 000000000..a3e6b6fdc --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_space_around__border_box_ltr.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_space_around__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_content_space_around__border_box_rtl.xml new file mode 100644 index 000000000..1b09bac1e --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_space_around__border_box_rtl.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_space_around__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_content_space_around__content_box_ltr.xml new file mode 100644 index 000000000..461f19cf2 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_space_around__content_box_ltr.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_content_space_around__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_content_space_around__content_box_rtl.xml new file mode 100644 index 000000000..2dc5f091a --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_content_space_around__content_box_rtl.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_center__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_items_center__border_box_ltr.xml new file mode 100644 index 000000000..1f489c323 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_center__border_box_ltr.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_center__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_items_center__border_box_rtl.xml new file mode 100644 index 000000000..c85d7e2ff --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_center__border_box_rtl.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_center__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_items_center__content_box_ltr.xml new file mode 100644 index 000000000..040953f75 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_center__content_box_ltr.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_center__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_items_center__content_box_rtl.xml new file mode 100644 index 000000000..826e6fb07 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_center__content_box_rtl.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_end__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_items_end__border_box_ltr.xml new file mode 100644 index 000000000..ff1992bd0 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_end__border_box_ltr.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_end__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_items_end__border_box_rtl.xml new file mode 100644 index 000000000..217f0fc07 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_end__border_box_rtl.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_end__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_items_end__content_box_ltr.xml new file mode 100644 index 000000000..75eb81e5f --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_end__content_box_ltr.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_end__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_items_end__content_box_rtl.xml new file mode 100644 index 000000000..28d82025c --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_end__content_box_rtl.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_gap__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_items_gap__border_box_ltr.xml new file mode 100644 index 000000000..728fe03b5 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_gap__border_box_ltr.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_gap__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_items_gap__border_box_rtl.xml new file mode 100644 index 000000000..a4dee0758 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_gap__border_box_rtl.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_gap__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_items_gap__content_box_ltr.xml new file mode 100644 index 000000000..e4c30c7b0 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_gap__content_box_ltr.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_gap__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_items_gap__content_box_rtl.xml new file mode 100644 index 000000000..87716ec6e --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_gap__content_box_rtl.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_normal__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_items_normal__border_box_ltr.xml new file mode 100644 index 000000000..64a33cbe4 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_normal__border_box_ltr.xml @@ -0,0 +1,23 @@ + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_normal__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_items_normal__border_box_rtl.xml new file mode 100644 index 000000000..ff0555ccf --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_normal__border_box_rtl.xml @@ -0,0 +1,23 @@ + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_normal__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_items_normal__content_box_ltr.xml new file mode 100644 index 000000000..323b55d7b --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_normal__content_box_ltr.xml @@ -0,0 +1,23 @@ + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_normal__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_items_normal__content_box_rtl.xml new file mode 100644 index 000000000..2283c6d19 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_normal__content_box_rtl.xml @@ -0,0 +1,23 @@ + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_rtl__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_items_rtl__border_box_ltr.xml new file mode 100644 index 000000000..6ed64c1a0 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_rtl__border_box_ltr.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_rtl__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_items_rtl__border_box_rtl.xml new file mode 100644 index 000000000..a04dd5599 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_rtl__border_box_rtl.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_rtl__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_items_rtl__content_box_ltr.xml new file mode 100644 index 000000000..338c9736d --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_rtl__content_box_ltr.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_rtl__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_items_rtl__content_box_rtl.xml new file mode 100644 index 000000000..acf9c5f49 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_rtl__content_box_rtl.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_stretch__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_items_stretch__border_box_ltr.xml new file mode 100644 index 000000000..c65783f30 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_stretch__border_box_ltr.xml @@ -0,0 +1,23 @@ + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_stretch__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_items_stretch__border_box_rtl.xml new file mode 100644 index 000000000..fd71d86e7 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_stretch__border_box_rtl.xml @@ -0,0 +1,23 @@ + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_stretch__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_items_stretch__content_box_ltr.xml new file mode 100644 index 000000000..b55364da5 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_stretch__content_box_ltr.xml @@ -0,0 +1,23 @@ + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_items_stretch__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_items_stretch__content_box_rtl.xml new file mode 100644 index 000000000..47ed8e0e9 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_items_stretch__content_box_rtl.xml @@ -0,0 +1,23 @@ + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_self_mixed__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_self_mixed__border_box_ltr.xml new file mode 100644 index 000000000..6ca5fd040 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_self_mixed__border_box_ltr.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_self_mixed__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_self_mixed__border_box_rtl.xml new file mode 100644 index 000000000..cf28d39fb --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_self_mixed__border_box_rtl.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_self_mixed__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_align_self_mixed__content_box_ltr.xml new file mode 100644 index 000000000..3c92627f9 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_self_mixed__content_box_ltr.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_align_self_mixed__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_align_self_mixed__content_box_rtl.xml new file mode 100644 index 000000000..dfff59458 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_align_self_mixed__content_box_rtl.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_dense_align_items_end__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_dense_align_items_end__border_box_ltr.xml new file mode 100644 index 000000000..6765219bb --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_dense_align_items_end__border_box_ltr.xml @@ -0,0 +1,23 @@ + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_dense_align_items_end__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_dense_align_items_end__border_box_rtl.xml new file mode 100644 index 000000000..7abc937a6 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_dense_align_items_end__border_box_rtl.xml @@ -0,0 +1,23 @@ + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_dense_align_items_end__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_dense_align_items_end__content_box_ltr.xml new file mode 100644 index 000000000..c71ccf6a5 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_dense_align_items_end__content_box_ltr.xml @@ -0,0 +1,23 @@ + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_dense_align_items_end__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_dense_align_items_end__content_box_rtl.xml new file mode 100644 index 000000000..fbdfbca0c --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_dense_align_items_end__content_box_rtl.xml @@ -0,0 +1,23 @@ + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_justify_content_center_row__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_justify_content_center_row__border_box_ltr.xml new file mode 100644 index 000000000..a62aada76 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_justify_content_center_row__border_box_ltr.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_justify_content_center_row__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_justify_content_center_row__border_box_rtl.xml new file mode 100644 index 000000000..7d411a3b6 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_justify_content_center_row__border_box_rtl.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_justify_content_center_row__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_justify_content_center_row__content_box_ltr.xml new file mode 100644 index 000000000..531294c47 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_justify_content_center_row__content_box_ltr.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_justify_content_center_row__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_justify_content_center_row__content_box_rtl.xml new file mode 100644 index 000000000..8b3ffbfa2 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_justify_content_center_row__content_box_rtl.xml @@ -0,0 +1,19 @@ + + + +
+
+
+
+
+
+ + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_justify_items_end_row__border_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_justify_items_end_row__border_box_ltr.xml new file mode 100644 index 000000000..2d476aee2 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_justify_items_end_row__border_box_ltr.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_justify_items_end_row__border_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_justify_items_end_row__border_box_rtl.xml new file mode 100644 index 000000000..d6f86b84c --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_justify_items_end_row__border_box_rtl.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_justify_items_end_row__content_box_ltr.xml b/tests/xml/grid_lanes/grid_lanes_justify_items_end_row__content_box_ltr.xml new file mode 100644 index 000000000..55cd2bfe1 --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_justify_items_end_row__content_box_ltr.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/grid_lanes/grid_lanes_justify_items_end_row__content_box_rtl.xml b/tests/xml/grid_lanes/grid_lanes_justify_items_end_row__content_box_rtl.xml new file mode 100644 index 000000000..1a9e0274f --- /dev/null +++ b/tests/xml/grid_lanes/grid_lanes_justify_items_end_row__content_box_rtl.xml @@ -0,0 +1,21 @@ + + + +
+
+
+
+
+
+
+ + + + + + + + + + + diff --git a/tests/xml/mod.rs b/tests/xml/mod.rs index 764cc4be1..a3657d626 100644 --- a/tests/xml/mod.rs +++ b/tests/xml/mod.rs @@ -36041,6 +36041,270 @@ mod grid { } mod grid_lanes { + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_center__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_center__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_center__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_center__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_center__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_center__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_center__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_center__content_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_end__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_end__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_end__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_end__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_end__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_end__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_end__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_end__content_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_safe_end__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_safe_end__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_safe_end__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_safe_end__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_safe_end__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_safe_end__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_safe_end__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_safe_end__content_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_space_around__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_space_around__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_space_around__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_space_around__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_space_around__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_space_around__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_content_space_around__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_content_space_around__content_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_center__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_center__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_center__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_center__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_center__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_center__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_center__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_center__content_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_end__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_end__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_end__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_end__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_end__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_end__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_end__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_end__content_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_gap__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_gap__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_gap__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_gap__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_gap__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_gap__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_gap__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_gap__content_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_normal__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_normal__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_normal__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_normal__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_normal__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_normal__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_normal__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_normal__content_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_rtl__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_rtl__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_rtl__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_rtl__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_rtl__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_rtl__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_rtl__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_rtl__content_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_stretch__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_stretch__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_stretch__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_stretch__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_stretch__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_stretch__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_items_stretch__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_items_stretch__content_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_self_mixed__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_self_mixed__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_self_mixed__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_self_mixed__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_self_mixed__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_self_mixed__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_align_self_mixed__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_align_self_mixed__content_box_rtl"); + } + #[cfg(feature = "grid_lanes")] #[test] fn grid_lanes_auto_tracks__border_box_ltr() { @@ -36305,6 +36569,30 @@ mod grid_lanes { crate::run_xml_test("grid_lanes", "grid_lanes_definite_placement__content_box_rtl"); } + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_dense_align_items_end__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_dense_align_items_end__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_dense_align_items_end__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_dense_align_items_end__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_dense_align_items_end__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_dense_align_items_end__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_dense_align_items_end__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_dense_align_items_end__content_box_rtl"); + } + #[cfg(feature = "grid_lanes")] #[test] fn grid_lanes_dense_backfill__border_box_ltr() { @@ -36761,6 +37049,54 @@ mod grid_lanes { crate::run_xml_test("grid_lanes", "grid_lanes_item_margins__content_box_rtl"); } + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_justify_content_center_row__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_justify_content_center_row__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_justify_content_center_row__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_justify_content_center_row__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_justify_content_center_row__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_justify_content_center_row__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_justify_content_center_row__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_justify_content_center_row__content_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_justify_items_end_row__border_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_justify_items_end_row__border_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_justify_items_end_row__content_box_ltr() { + crate::run_xml_test("grid_lanes", "grid_lanes_justify_items_end_row__content_box_ltr"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_justify_items_end_row__border_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_justify_items_end_row__border_box_rtl"); + } + + #[cfg(feature = "grid_lanes")] + #[test] + fn grid_lanes_justify_items_end_row__content_box_rtl() { + crate::run_xml_test("grid_lanes", "grid_lanes_justify_items_end_row__content_box_rtl"); + } + #[cfg(feature = "grid_lanes")] #[test] fn grid_lanes_min_max_content_tracks__border_box_ltr() { From dad1597d6ca27ca512ca49340ae0814104cc0c11 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Thu, 8 Oct 2026 18:19:08 +0000 Subject: [PATCH 2/2] Reference #1275 in the changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 372def0d3..7e4d727be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -60,7 +60,7 @@ ### Added -- Initial support for CSS Grid Level 3 [Grid Lanes](https://drafts.csswg.org/css-grid-3/) behind the new `grid_lanes` feature (#1270). `Display::GridLanes` lays items out in a waterfall along the stacking axis of a container whose tracks are defined in the other axis (`GridLanesDirection`; `Style::grid_lanes_direction` / `GridContainerStyle::grid_lanes_direction()`), with the auto-placement tie threshold set by `Style::fit_tolerance` / `GridContainerStyle::fit_tolerance()` (a `LengthPercentage`; `infinite` is `LengthPercentage::length(f32::INFINITY)`). The new trait getters have default implementations. Auto-placed items contribute to intrinsic grid-axis track sizes through the spec's virtual-item optimization (#1272). Containers whose `grid_auto_flow` is dense backfill items into skipped spaces (#1274). `align_content`/`justify_content` in the stacking axis moves the stacking range as a whole, and items adjacent to a gap (the last item in a track, or one followed by a spanning item) align within their margin box plus that gap with `align_self`/`justify_self`; baseline alignment in the stacking axis falls back to `start` (#TODO). Absolutely positioned children follow in a later release +- Initial support for CSS Grid Level 3 [Grid Lanes](https://drafts.csswg.org/css-grid-3/) behind the new `grid_lanes` feature (#1270). `Display::GridLanes` lays items out in a waterfall along the stacking axis of a container whose tracks are defined in the other axis (`GridLanesDirection`; `Style::grid_lanes_direction` / `GridContainerStyle::grid_lanes_direction()`), with the auto-placement tie threshold set by `Style::fit_tolerance` / `GridContainerStyle::fit_tolerance()` (a `LengthPercentage`; `infinite` is `LengthPercentage::length(f32::INFINITY)`). The new trait getters have default implementations. Auto-placed items contribute to intrinsic grid-axis track sizes through the spec's virtual-item optimization (#1272). Containers whose `grid_auto_flow` is dense backfill items into skipped spaces (#1274). `align_content`/`justify_content` in the stacking axis moves the stacking range as a whole, and items adjacent to a gap (the last item in a track, or one followed by a spanning item) align within their margin box plus that gap with `align_self`/`justify_self`; baseline alignment in the stacking axis falls back to `start` (#1275). Absolutely positioned children follow in a later release - `CoreStyle::is_replaced()` (defaulting to `false`; `Style::item_is_replaced`) now identifies [replaced elements](https://html.spec.whatwg.org/multipage/rendering.html#replaced-elements) for absolute positioning: only these (and tables) are exempt from being stretched between their insets under `normal` alignment. `CoreStyle::is_compressible_replaced()` now has its css-sizing meaning of [compressible replaced element](https://drafts.csswg.org/css-sizing-3/#compressible) — replaced elements *plus* form controls with an intrinsic size (`input`, `select`, `textarea`, `progress`, `meter`) — and is what block layout consults when deciding that an auto-width block-level box takes its intrinsic width rather than being stretched (matching browsers, where a block-level `` keeps its intrinsic width but a `position: absolute; left: 0; right: 0` one is stretched). `Style` gains `item_is_compressible_replaced` for the form-control case; `item_is_replaced: true` continues to imply both. - `AlignSelf::is_stretch_or_normal` returns whether an alignment's keyword is `Stretch` or `Normal` - `AlignItems`, `AlignItemsKeyword` and `AlignmentSafety` now implement `Default` (`AlignItems::NORMAL`, `AlignItemsKeyword::Normal` and `AlignmentSafety::Default`)