gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 1090HTML 1022Markdown 12TOML 84418 Definiciones

Grid: baseline alignment support (#344)

* Use span method on Line<OriginZeroLine>

* Inline has_max_content_max_track_sizing_function closure

* Single track span optimisation

* Move IntrisicSizeMeasurer to top level of module

* Add align_self and justify_self properties to GridItem struct

* Implement basic baseline alignment for CSS Grid

* Enable CSS Grid baseline alignment test

* Compute grid container baseline

* Port all flexbox baseline alignment tests to css grid

* Fix clippy lints

ab747b81e56af728da931e70c58a61013639aea3 · por Nico Burns · (hace 3 años) · padre ebd376fbe · ver el árbol en este commit

Delta semántico · 82

benches/generated/grid_align_items_baseline.rs

benches/generated/grid_align_items_baseline_child.rs

benches/generated/grid_align_items_baseline_child_margin.rs

benches/generated/grid_align_items_baseline_child_margin_percent.rs

benches/generated/grid_align_items_baseline_child_multiline.rs

benches/generated/grid_align_items_baseline_child_multiline_no_override_on_secondline.rs

benches/generated/grid_align_items_baseline_child_multiline_override.rs

benches/generated/grid_align_items_baseline_child_padding.rs

benches/generated/grid_align_items_baseline_child_top.rs

benches/generated/grid_align_items_baseline_child_top2.rs

benches/generated/grid_align_items_baseline_complex.rs

benches/generated/grid_align_items_baseline_double_nested_child.rs

benches/generated/grid_align_items_baseline_multiline.rs

benches/generated/grid_align_items_baseline_multiline_column.rs

benches/generated/grid_align_items_baseline_multiline_row_and_column.rs

benches/generated/grid_align_items_baseline_nested_column.rs

src/compute/grid/alignment.rs

src/compute/grid/mod.rs

  • cambió por dentro fn compute pub

src/compute/grid/placement.rs

src/compute/grid/track_sizing.rs

src/compute/grid/types/grid_item.rs

tests/generated/grid_align_items_baseline.rs

tests/generated/grid_align_items_baseline_child.rs

tests/generated/grid_align_items_baseline_child_margin.rs

tests/generated/grid_align_items_baseline_child_margin_percent.rs

tests/generated/grid_align_items_baseline_child_multiline.rs

tests/generated/grid_align_items_baseline_child_multiline_no_override_on_secondline.rs

tests/generated/grid_align_items_baseline_child_multiline_override.rs

tests/generated/grid_align_items_baseline_child_padding.rs

tests/generated/grid_align_items_baseline_child_top.rs

tests/generated/grid_align_items_baseline_child_top2.rs

tests/generated/grid_align_items_baseline_complex.rs

tests/generated/grid_align_items_baseline_double_nested_child.rs

tests/generated/grid_align_items_baseline_multiline.rs

tests/generated/grid_align_items_baseline_multiline_column.rs

tests/generated/grid_align_items_baseline_multiline_row_and_column.rs

tests/generated/grid_align_items_baseline_nested_column.rs

56 archivos · +3754 −165

diff --git a/benches/generated/grid_align_items_baseline.rs b/benches/generated/grid_align_items_baseline.rs
new file mode 100644
index 000000000..64bde21cf
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline.rs
@@ -0,0 +1,40 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_child.rs b/benches/generated/grid_align_items_baseline_child.rs
new file mode 100644
index 000000000..0659f1e7f
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_child.rs
@@ -0,0 +1,53 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_child_margin.rs b/benches/generated/grid_align_items_baseline_child_margin.rs
new file mode 100644
index 000000000..45c62c125
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_child_margin.rs
@@ -0,0 +1,65 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            margin: taffy::geometry::Rect {
+                left: taffy::style::LengthPercentageAuto::Points(5f32),
+                right: taffy::style::LengthPercentageAuto::Points(5f32),
+                top: taffy::style::LengthPercentageAuto::Points(5f32),
+                bottom: taffy::style::LengthPercentageAuto::Points(5f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            margin: taffy::geometry::Rect {
+                left: taffy::style::LengthPercentageAuto::Points(5f32),
+                right: taffy::style::LengthPercentageAuto::Points(5f32),
+                top: taffy::style::LengthPercentageAuto::Points(5f32),
+                bottom: taffy::style::LengthPercentageAuto::Points(5f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_child_margin_percent.rs b/benches/generated/grid_align_items_baseline_child_margin_percent.rs
new file mode 100644
index 000000000..c97ba2713
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_child_margin_percent.rs
@@ -0,0 +1,65 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            margin: taffy::geometry::Rect {
+                left: taffy::style::LengthPercentageAuto::Percent(0.05f32),
+                right: taffy::style::LengthPercentageAuto::Percent(0.05f32),
+                top: taffy::style::LengthPercentageAuto::Percent(0.05f32),
+                bottom: taffy::style::LengthPercentageAuto::Percent(0.05f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            margin: taffy::geometry::Rect {
+                left: taffy::style::LengthPercentageAuto::Percent(0.01f32),
+                right: taffy::style::LengthPercentageAuto::Percent(0.01f32),
+                top: taffy::style::LengthPercentageAuto::Percent(0.01f32),
+                bottom: taffy::style::LengthPercentageAuto::Percent(0.01f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_child_multiline.rs b/benches/generated/grid_align_items_baseline_child_multiline.rs
new file mode 100644
index 000000000..d20c5697e
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_child_multiline.rs
@@ -0,0 +1,79 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(60f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node11 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node12 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node13 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                flex_wrap: taffy::style::FlexWrap::Wrap,
+                grid_template_columns: vec![auto(), auto()],
+                size: taffy::geometry::Size { width: taffy::style::Dimension::Points(50f32), height: auto() },
+                ..Default::default()
+            },
+            &[node10, node11, node12, node13],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size { width: taffy::style::Dimension::Points(100f32), height: auto() },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_child_multiline_no_override_on_secondline.rs b/benches/generated/grid_align_items_baseline_child_multiline_no_override_on_secondline.rs
new file mode 100644
index 000000000..6eaa635e3
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_child_multiline_no_override_on_secondline.rs
@@ -0,0 +1,85 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(60f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node11 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node12 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node13 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            align_self: Some(taffy::style::AlignSelf::Baseline),
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_columns: vec![auto(), auto()],
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(25f32),
+                },
+                ..Default::default()
+            },
+            &[node10, node11, node12, node13],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_child_multiline_override.rs b/benches/generated/grid_align_items_baseline_child_multiline_override.rs
new file mode 100644
index 000000000..0d2fe8215
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_child_multiline_override.rs
@@ -0,0 +1,85 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(60f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node11 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            align_self: Some(taffy::style::AlignSelf::Baseline),
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node12 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node13 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            align_self: Some(taffy::style::AlignSelf::Baseline),
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(25f32),
+                },
+                ..Default::default()
+            },
+            &[node10, node11, node12, node13],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_child_padding.rs b/benches/generated/grid_align_items_baseline_child_padding.rs
new file mode 100644
index 000000000..6a2a8c991
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_child_padding.rs
@@ -0,0 +1,65 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                padding: taffy::geometry::Rect {
+                    left: taffy::style::LengthPercentage::Points(5f32),
+                    right: taffy::style::LengthPercentage::Points(5f32),
+                    top: taffy::style::LengthPercentage::Points(5f32),
+                    bottom: taffy::style::LengthPercentage::Points(5f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                padding: taffy::geometry::Rect {
+                    left: taffy::style::LengthPercentage::Points(5f32),
+                    right: taffy::style::LengthPercentage::Points(5f32),
+                    top: taffy::style::LengthPercentage::Points(5f32),
+                    bottom: taffy::style::LengthPercentage::Points(5f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_child_top.rs b/benches/generated/grid_align_items_baseline_child_top.rs
new file mode 100644
index 000000000..8dd0b90ce
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_child_top.rs
@@ -0,0 +1,59 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            inset: taffy::geometry::Rect {
+                left: auto(),
+                right: auto(),
+                top: taffy::style::LengthPercentageAuto::Points(10f32),
+                bottom: auto(),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_child_top2.rs b/benches/generated/grid_align_items_baseline_child_top2.rs
new file mode 100644
index 000000000..7ed857b1d
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_child_top2.rs
@@ -0,0 +1,59 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                inset: taffy::geometry::Rect {
+                    left: auto(),
+                    right: auto(),
+                    top: taffy::style::LengthPercentageAuto::Points(5f32),
+                    bottom: auto(),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_complex.rs b/benches/generated/grid_align_items_baseline_complex.rs
new file mode 100644
index 000000000..ba4100c09
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_complex.rs
@@ -0,0 +1,139 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(20f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Points(10f32) },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(20f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node20 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Points(10f32) },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(20f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node20],
+        )
+        .unwrap();
+    let node3 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(20f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node4 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(20f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node5 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(20f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node60 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Points(10f32) },
+            ..Default::default()
+        })
+        .unwrap();
+    let node6 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(20f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node60],
+        )
+        .unwrap();
+    let node70 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Points(5f32) },
+            ..Default::default()
+        })
+        .unwrap();
+    let node7 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(20f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node70],
+        )
+        .unwrap();
+    let node8 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(20f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
+                grid_template_columns: vec![points(40f32), points(40f32), points(40f32)],
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(120f32),
+                    height: taffy::style::Dimension::Points(120f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1, node2, node3, node4, node5, node6, node7, node8],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_double_nested_child.rs b/benches/generated/grid_align_items_baseline_double_nested_child.rs
new file mode 100644
index 000000000..f28ebadc8
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_double_nested_child.rs
@@ -0,0 +1,66 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node00 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node0 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(50f32),
+                },
+                ..Default::default()
+            },
+            &[node00],
+        )
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(15f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_multiline.rs b/benches/generated/grid_align_items_baseline_multiline.rs
new file mode 100644
index 000000000..1e3b070d2
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_multiline.rs
@@ -0,0 +1,87 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node20 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node20],
+        )
+        .unwrap();
+    let node3 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                grid_template_columns: vec![auto(), auto()],
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1, node2, node3],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_multiline_column.rs b/benches/generated/grid_align_items_baseline_multiline_column.rs
new file mode 100644
index 000000000..5b3d9ba6a
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_multiline_column.rs
@@ -0,0 +1,87 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(20f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(30f32),
+                    height: taffy::style::Dimension::Points(50f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node20 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(10f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(40f32),
+                    height: taffy::style::Dimension::Points(70f32),
+                },
+                ..Default::default()
+            },
+            &[node20],
+        )
+        .unwrap();
+    let node3 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                grid_template_columns: vec![auto(), auto()],
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1, node2, node3],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_multiline_row_and_column.rs b/benches/generated/grid_align_items_baseline_multiline_row_and_column.rs
new file mode 100644
index 000000000..2fb0836a3
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_multiline_row_and_column.rs
@@ -0,0 +1,87 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(50f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node20 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node20],
+        )
+        .unwrap();
+    let node3 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                grid_template_columns: vec![auto(), auto()],
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1, node2, node3],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_align_items_baseline_nested_column.rs b/benches/generated/grid_align_items_baseline_nested_column.rs
new file mode 100644
index 000000000..1ce6fb71d
--- /dev/null
+++ b/benches/generated/grid_align_items_baseline_nested_column.rs
@@ -0,0 +1,69 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(60f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node100 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(30f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node101 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(40f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(80f32),
+                },
+                ..Default::default()
+            },
+            &[node100, node101],
+        )
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style { display: taffy::style::Display::Grid, ..Default::default() },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/mod.rs b/benches/generated/mod.rs
index b83f9958a..6dc849d6c 100644
--- a/benches/generated/mod.rs
+++ b/benches/generated/mod.rs
@@ -363,6 +363,38 @@ mod grid_align_content_start;
 #[cfg(feature = "grid")]
 mod grid_align_content_start_with_padding_border;
 #[cfg(feature = "grid")]
+mod grid_align_items_baseline;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_margin;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_margin_percent;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_multiline;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_multiline_no_override_on_secondline;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_multiline_override;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_padding;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_top;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_top2;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_complex;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_double_nested_child;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_multiline;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_multiline_column;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_multiline_row_and_column;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_nested_column;
+#[cfg(feature = "grid")]
 mod grid_align_items_sized_center;
 #[cfg(feature = "grid")]
 mod grid_align_items_sized_end;
@@ -1058,6 +1090,38 @@ fn benchmark(c: &mut Criterion) {
             #[cfg(feature = "grid")]
             grid_align_content_start_with_padding_border::compute();
             #[cfg(feature = "grid")]
+            grid_align_items_baseline::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_child::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_child_margin::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_child_margin_percent::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_child_multiline::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_child_multiline_no_override_on_secondline::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_child_multiline_override::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_child_padding::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_child_top::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_child_top2::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_complex::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_double_nested_child::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_multiline::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_multiline_column::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_multiline_row_and_column::compute();
+            #[cfg(feature = "grid")]
+            grid_align_items_baseline_nested_column::compute();
+            #[cfg(feature = "grid")]
             grid_align_items_sized_center::compute();
             #[cfg(feature = "grid")]
             grid_align_items_sized_end::compute();
diff --git a/src/compute/grid/alignment.rs b/src/compute/grid/alignment.rs
index 1794eea0f..82c901818 100644
--- a/src/compute/grid/alignment.rs
+++ b/src/compute/grid/alignment.rs
@@ -78,6 +78,7 @@ pub(super) fn align_and_position_item(
     order: u32,
     grid_area: Rect<f32>,
     container_alignment_styles: InBothAbsAxis<Option<AlignItems>>,
+    baseline_shim: f32,
 ) {
     let grid_area_size = Size { width: grid_area.right - grid_area.left, height: grid_area.bottom - grid_area.top };
 
@@ -117,9 +118,10 @@ pub(super) fn align_and_position_item(
     // Note: This is not a bug. It is part of the CSS spec that both horizontal and vertical margins
     // resolve against the WIDTH of the grid area.
     let margin = style.margin.map(|margin| margin.resolve_to_option(grid_area_size.width));
+
     let grid_area_minus_item_margins_size = Size {
         width: grid_area_size.width.maybe_sub(margin.left).maybe_sub(margin.right),
-        height: grid_area_size.height.maybe_sub(margin.top).maybe_sub(margin.bottom),
+        height: grid_area_size.height.maybe_sub(margin.top).maybe_sub(margin.bottom) - baseline_shim,
     };
 
     // If node is absolutely positioned and width is not set explicitly, then deduce it
@@ -198,6 +200,7 @@ pub(super) fn align_and_position_item(
         position,
         inset_horizontal,
         margin.horizontal_components(),
+        0.0,
     );
     let y = align_item_within_area(
         Line { start: grid_area.top, end: grid_area.bottom },
@@ -206,6 +209,7 @@ pub(super) fn align_and_position_item(
         position,
         inset_vertical,
         margin.vertical_components(),
+        baseline_shim,
     );
 
     *tree.layout_mut(node) = Layout { order, size: Size { width, height }, location: Point { x, y } };
@@ -219,17 +223,20 @@ pub(super) fn align_item_within_area(
     position: Position,
     inset: Line<Option<f32>>,
     margin: Line<Option<f32>>,
+    baseline_shim: f32,
 ) -> f32 {
     // Calculate grid area dimension in the axis
-    let non_auto_margin = Line { start: margin.start.unwrap_or(0.0), end: margin.end.unwrap_or(0.0) };
+    let non_auto_margin = Line { start: margin.start.unwrap_or(0.0) + baseline_shim, end: margin.end.unwrap_or(0.0) };
     let grid_area_size = f32_max(grid_area.end - grid_area.start, 0.0);
     let free_space = f32_max(grid_area_size - resolved_size - non_auto_margin.sum(), 0.0);
 
     // Expand auto margins to fill available space
     let auto_margin_count = margin.start.is_none() as u8 + margin.end.is_none() as u8;
     let auto_margin_size = if auto_margin_count > 0 { free_space / auto_margin_count as f32 } else { 0.0 };
-    let resolved_margin =
-        Line { start: margin.start.unwrap_or(auto_margin_size), end: margin.end.unwrap_or(auto_margin_size) };
+    let resolved_margin = Line {
+        start: margin.start.unwrap_or(auto_margin_size) + baseline_shim,
+        end: margin.end.unwrap_or(auto_margin_size),
+    };
 
     // Compute offset in the axis
     let alignment_based_offset = match alignment_style {
diff --git a/src/compute/grid/mod.rs b/src/compute/grid/mod.rs
index 3b114e6cc..3911d49ef 100644
--- a/src/compute/grid/mod.rs
+++ b/src/compute/grid/mod.rs
@@ -6,7 +6,7 @@ use crate::layout::{Layout, RunMode, SizeAndBaselines, SizingMode};
 use crate::math::MaybeMath;
 use crate::node::Node;
 use crate::resolve::{MaybeResolve, ResolveOrZero};
-use crate::style::{AlignContent, AvailableSpace, Display, Position};
+use crate::style::{AlignContent, AlignItems, AlignSelf, AvailableSpace, Display, Position};
 use crate::style_helpers::*;
 use crate::sys::{GridTrackVec, Vec};
 use crate::tree::LayoutTree;
@@ -95,7 +95,6 @@ pub fn compute(
     // Match items (children) to a definite grid position (row start/end and column start/end position)
     let mut items = Vec::with_capacity(tree.child_count(node));
     let mut cell_occupancy_matrix = CellOccupancyMatrix::with_track_counts(est_col_counts, est_row_counts);
-    let grid_auto_flow = style.grid_auto_flow;
     let in_flow_children_iter = || {
         tree.children(node)
             .copied()
@@ -103,7 +102,13 @@ pub fn compute(
             .map(|(index, child_node)| (index, child_node, tree.style(child_node)))
             .filter(|(_, _, style)| style.display != Display::None && style.position != Position::Absolute)
     };
-    place_grid_items(&mut cell_occupancy_matrix, &mut items, in_flow_children_iter, grid_auto_flow);
+    place_grid_items(
+        &mut cell_occupancy_matrix,
+        &mut items,
+        in_flow_children_iter,
+        style.grid_auto_flow,
+        style.align_items.unwrap_or(AlignItems::Stretch),
+    );
 
     // Extract track counts from previous step (auto-placement can expand the number of tracks)
     let final_col_counts = *cell_occupancy_matrix.track_counts(AbsoluteAxis::Horizontal);
@@ -179,6 +184,9 @@ pub fn compute(
     // Record this as a boolean (per-axis) on each item for later use in the track-sizing algorithm
     determine_if_item_crosses_flexible_or_intrinsic_tracks(&mut items, &columns, &rows);
 
+    // Determine if the grid has any baseline aligned items
+    let has_baseline_aligned_item = items.iter().any(|item| item.align_self == AlignSelf::Baseline);
+
     // Run track sizing algorithm for Inline axis
     track_sizing_algorithm(
         tree,
@@ -192,6 +200,7 @@ pub fn compute(
         &mut rows,
         &mut items,
         |track: &GridTrack, parent_size: Option<f32>| track.max_track_sizing_function.definite_value(parent_size),
+        has_baseline_aligned_item,
     );
     let initial_column_sum = columns.iter().map(|track| track.base_size).sum::<f32>();
     inner_node_size.width = inner_node_size.width.or_else(|| initial_column_sum.into());
@@ -211,6 +220,7 @@ pub fn compute(
         &mut columns,
         &mut items,
         |track: &GridTrack, _| Some(track.base_size),
+        false, // TODO: Support baseline alignment in the vertical axis
     );
     let initial_row_sum = rows.iter().map(|track| track.base_size).sum::<f32>();
     inner_node_size.height = inner_node_size.height.or_else(|| initial_row_sum.into());
@@ -286,6 +296,7 @@ pub fn compute(
             &mut rows,
             &mut items,
             |track: &GridTrack, _| Some(track.base_size),
+            has_baseline_aligned_item,
         );
 
         // Row sizing must be re-run (once) if:
@@ -339,6 +350,7 @@ pub fn compute(
                 &mut columns,
                 &mut items,
                 |track: &GridTrack, _| Some(track.base_size),
+                false, // TODO: Support baseline alignment in the vertical axis
             );
         }
     }
@@ -397,7 +409,14 @@ pub fn compute(
             left: columns[item.column_indexes.start as usize + 1].offset,
             right: columns[item.column_indexes.end as usize].offset,
         };
-        align_and_position_item(tree, item.node, index as u32, grid_area, container_alignment_styles);
+        align_and_position_item(
+            tree,
+            item.node,
+            index as u32,
+            grid_area,
+            container_alignment_styles,
+            item.baseline_shim,
+        );
     }
 
     // Position hidden and absolutely positioned children
@@ -454,10 +473,43 @@ pub fn compute(
                     .map(|index| columns[index].offset)
                     .unwrap_or(container_border_box.width - border.right),
             };
-            align_and_position_item(tree, child, order, grid_area, container_alignment_styles);
+            // TODO: Baseline alignment support for absolutely positioned items (should check if is actuallty specified)
+            align_and_position_item(tree, child, order, grid_area, container_alignment_styles, 0.0);
             order += 1;
         }
     });
 
-    SizeAndBaselines { size: container_border_box, first_baselines: Point::NONE }
+    // If there are not items then return just the container size (no baseline)
+    if items.is_empty() {
+        return SizeAndBaselines { size: container_border_box, first_baselines: Point::NONE };
+    }
+
+    // Determine the grid container baseline(s) (currently we only compute the first baseline)
+    let grid_container_baseline: f32 = {
+        // Sort items by row start position so that we can iterate items in groups which are in the same row
+        items.sort_by_key(|item| item.row_indexes.start);
+
+        // Get the row index of the first row containing items
+        let first_row = items[0].row_indexes.start;
+
+        // Create a slice of all of the items start in this row (taking advantage of the fact that we have just sorted the array)
+        let first_row_items = &items[0..].split(|item| item.row_indexes.start != first_row).next().unwrap();
+
+        // Check if any items in *this row* are baseline aligned
+        let row_has_baseline_item = first_row_items.iter().any(|item| item.align_self == AlignSelf::Baseline);
+
+        let item = if row_has_baseline_item {
+            first_row_items.iter().find(|item| item.align_self == AlignSelf::Baseline).unwrap()
+        } else {
+            &first_row_items[0]
+        };
+
+        let layout = tree.layout_mut(item.node);
+        layout.location.y + item.baseline.unwrap_or(layout.size.height)
+    };
+
+    SizeAndBaselines {
+        size: container_border_box,
+        first_baselines: Point { x: None, y: Some(grid_container_baseline) },
+    }
 }
diff --git a/src/compute/grid/placement.rs b/src/compute/grid/placement.rs
index a05deb136..5d829b804 100644
--- a/src/compute/grid/placement.rs
+++ b/src/compute/grid/placement.rs
@@ -5,7 +5,7 @@ use super::OriginZeroLine;
 use crate::axis::{AbsoluteAxis, InBothAbsAxis};
 use crate::geometry::Line;
 use crate::node::Node;
-use crate::style::{GridAutoFlow, OriginZeroGridPlacement, Style};
+use crate::style::{AlignItems, GridAutoFlow, OriginZeroGridPlacement, Style};
 use crate::sys::Vec;
 
 /// 8.5. Grid Item Placement Algorithm
@@ -17,6 +17,7 @@ pub(super) fn place_grid_items<'a, ChildIter>(
     items: &mut Vec<GridItem>,
     children_iter: impl Fn() -> ChildIter,
     grid_auto_flow: GridAutoFlow,
+    align_items: AlignItems,
 ) where
     ChildIter: Iterator<Item = (usize, Node, &'a Style)>,
 {
@@ -52,6 +53,7 @@ pub(super) fn place_grid_items<'a, ChildIter>(
                 child_node,
                 index,
                 style,
+                align_items,
                 primary_axis,
                 row_span,
                 col_span,
@@ -81,6 +83,7 @@ pub(super) fn place_grid_items<'a, ChildIter>(
                 child_node,
                 index,
                 style,
+                align_items,
                 primary_axis,
                 primary_span,
                 secondary_span,
@@ -135,6 +138,7 @@ pub(super) fn place_grid_items<'a, ChildIter>(
                 child_node,
                 index,
                 style,
+                align_items,
                 primary_axis,
                 primary_span,
                 secondary_span,
@@ -292,6 +296,7 @@ fn record_grid_placement(
     node: Node,
     index: usize,
     style: &Style,
+    parent_align_items: AlignItems,
     primary_axis: AbsoluteAxis,
     primary_span: Line<OriginZeroLine>,
     secondary_span: Line<OriginZeroLine>,
@@ -310,7 +315,14 @@ fn record_grid_placement(
         AbsoluteAxis::Horizontal => (primary_span, secondary_span),
         AbsoluteAxis::Vertical => (secondary_span, primary_span),
     };
-    items.push(GridItem::new_with_placement_style_and_order(node, col_span, row_span, style, index as u16));
+    items.push(GridItem::new_with_placement_style_and_order(
+        node,
+        col_span,
+        row_span,
+        style,
+        parent_align_items,
+        index as u16,
+    ));
 
     #[cfg(test)]
     println!("AFTER placement:");
@@ -356,7 +368,7 @@ mod tests {
                 CellOccupancyMatrix::with_track_counts(estimated_sizes.0, estimated_sizes.1);
 
             // Run placement algorithm
-            place_grid_items(&mut cell_occupancy_matrix, &mut items, children_iter, flow);
+            place_grid_items(&mut cell_occupancy_matrix, &mut items, children_iter, flow, AlignSelf::Start);
 
             // Assert that each item has been placed in the right location
             let mut sorted_children = children.clone();
diff --git a/src/compute/grid/track_sizing.rs b/src/compute/grid/track_sizing.rs
index 134d50f0b..494748650 100644
--- a/src/compute/grid/track_sizing.rs
+++ b/src/compute/grid/track_sizing.rs
@@ -2,11 +2,15 @@
 //! https://www.w3.org/TR/css-grid-1/#layout-algorithm
 use super::types::{GridItem, GridTrack, TrackCounts};
 use crate::axis::AbstractAxis;
+use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
 use crate::geometry::{Rect, Size};
+use crate::layout::SizingMode;
 use crate::math::MaybeMath;
-use crate::prelude::LayoutTree;
+use crate::prelude::{LayoutTree, TaffyMinContent};
 use crate::resolve::ResolveOrZero;
-use crate::style::{AlignContent, AvailableSpace, MaxTrackSizingFunction, MinTrackSizingFunction};
+use crate::style::{
+    AlignContent, AlignSelf, AvailableSpace, LengthPercentage, MaxTrackSizingFunction, MinTrackSizingFunction,
+};
 use crate::sys::{f32_max, f32_min};
 use core::cmp::Ordering;
 
@@ -62,6 +66,95 @@ impl ItemBatcher {
     }
 }
 
+/// This struct captures a bunch of variables which are used to compute the intrinsic sizes of children so that those variables
+/// don't have to be passed around all over the place below. It then has methods that implement the intrinsic sizing computations
+struct IntrisicSizeMeasurer<'tree, 'oat, Tree, EstimateFunction>
+where
+    Tree: LayoutTree,
+    EstimateFunction: Fn(&GridTrack, Option<f32>) -> Option<f32>,
+{
+    /// The layout tree
+    tree: &'tree mut Tree,
+    /// The tracks in the opposite axis to the one we are currently sizing
+    other_axis_tracks: &'oat [GridTrack],
+    /// A function that computes an estimate of an other-axis track's size which is passed to
+    /// the child size measurement functions
+    get_track_size_estimate: EstimateFunction,
+    /// The axis we are currently sizing
+    axis: AbstractAxis,
+    /// The available grid space
+    inner_node_size: Size<Option<f32>>,
+}
+
+impl<'tree, 'oat, Tree, EstimateFunction> IntrisicSizeMeasurer<'tree, 'oat, Tree, EstimateFunction>
+where
+    Tree: LayoutTree,
+    EstimateFunction: Fn(&GridTrack, Option<f32>) -> Option<f32>,
+{
+    /// Compute the known_dimensions to be passed to the child sizing functions
+    /// These are estimates based on either the max track sizing function or the provisional base size in the opposite
+    /// axis to the one currently being sized.
+    /// https://www.w3.org/TR/css-grid-1/#algo-overview
+    #[inline(always)]
+    fn known_dimensions(&self, item: &mut GridItem) -> Size<Option<f32>> {
+        item.known_dimensions_cached(
+            self.axis,
+            self.other_axis_tracks,
+            self.inner_node_size.get(self.axis.other()),
+            &self.get_track_size_estimate,
+        )
+    }
+
+    /// Compute the item's resolved margins for size contributions. Horizontal percentage margins always resolve
+    /// to zero if the container size is indefinite as otherwise this would introduce a cyclic dependency.
+    #[inline(always)]
+    fn margins_axis_sums_with_baseline_shims(&self, item: &mut GridItem) -> Size<f32> {
+        let parent_width = self.inner_node_size.width;
+        Rect {
+            left: item.margin.left.resolve_or_zero(Some(0.0)),
+            right: item.margin.right.resolve_or_zero(Some(0.0)),
+            top: item.margin.top.resolve_or_zero(parent_width) + item.baseline_shim,
+            bottom: item.margin.bottom.resolve_or_zero(parent_width),
+        }
+        .sum_axes()
+    }
+
+    /// Retrieve the item's min content contribution from the cache or compute it using the provided parameters
+    #[inline(always)]
+    fn min_content_contribution(&mut self, item: &mut GridItem) -> f32 {
+        let known_dimensions = self.known_dimensions(item);
+        let margin_axis_sums = self.margins_axis_sums_with_baseline_shims(item);
+        let contribution =
+            item.min_content_contribution_cached(self.axis, self.tree, known_dimensions, self.inner_node_size);
+        contribution + margin_axis_sums.get(self.axis)
+    }
+
+    /// Retrieve the item's max content contribution from the cache or compute it using the provided parameters
+    #[inline(always)]
+    fn max_content_contribution(&mut self, item: &mut GridItem) -> f32 {
+        let known_dimensions = self.known_dimensions(item);
+        let margin_axis_sums = self.margins_axis_sums_with_baseline_shims(item);
+        let contribution =
+            item.max_content_contribution_cached(self.axis, self.tree, known_dimensions, self.inner_node_size);
+        contribution + margin_axis_sums.get(self.axis)
+    }
+
+    /// The minimum contribution of an item is the smallest outer size it can have.
+    /// Specifically:
+    ///   - If the item’s computed preferred size behaves as auto or depends on the size of its containing block in the relevant axis:
+    ///     Its minimum contribution is the outer size that would result from assuming the item’s used minimum size as its preferred size;
+    ///   - Else the item’s minimum contribution is its min-content contribution.
+    /// Because the minimum contribution often depends on the size of the item’s content, it is considered a type of intrinsic size contribution.
+    #[inline(always)]
+    fn minimum_contribution(&mut self, item: &mut GridItem, axis_tracks: &[GridTrack]) -> f32 {
+        let known_dimensions = self.known_dimensions(item);
+        let margin_axis_sums = self.margins_axis_sums_with_baseline_shims(item);
+        let contribution =
+            item.minimum_contribution_cached(self.tree, self.axis, axis_tracks, known_dimensions, self.inner_node_size);
+        contribution + margin_axis_sums.get(self.axis)
+    }
+}
+
 /// To make track sizing efficient we want to order tracks
 /// Here a placement is either a Line<i16> representing a row-start/row-end or a column-start/column-end
 #[inline(always)]
@@ -75,9 +168,7 @@ pub(super) fn cmp_by_cross_flex_then_span_then_start(
             _ => {
                 let placement_a = item_a.placement(axis);
                 let placement_b = item_b.placement(axis);
-                let a_span = placement_a.end - placement_a.start;
-                let b_span = placement_b.end - placement_b.start;
-                match a_span.cmp(&b_span) {
+                match placement_a.span().cmp(&placement_b.span()) {
                     Ordering::Less => Ordering::Less,
                     Ordering::Greater => Ordering::Greater,
                     Ordering::Equal => placement_a.start.cmp(&placement_b.start),
@@ -192,11 +283,17 @@ pub(super) fn track_sizing_algorithm<Tree: LayoutTree>(
     other_axis_tracks: &mut [GridTrack],
     items: &mut [GridItem],
     get_track_size_estimate: impl Fn(&GridTrack, Option<f32>) -> Option<f32>,
+    has_baseline_aligned_item: bool,
 ) {
     // 11.4 Initialise Track sizes
     // Initialize each track’s base size and growth limit.
     initialize_track_sizes(axis_tracks, inner_node_size.get(axis));
 
+    // 11.5.1 Shim item baselines
+    if has_baseline_aligned_item {
+        resolve_item_baselines(tree, axis, items, inner_node_size);
+    }
+
     // If all tracks have base_size = growth_limit, then skip the rest of this function.
     // Note: this can only happen both track sizing function have the same fixed track sizing function
     if axis_tracks.iter().all(|track| track.base_size == track.growth_limit) {
@@ -205,11 +302,6 @@ pub(super) fn track_sizing_algorithm<Tree: LayoutTree>(
 
     // Pre-computations for 11.5 Resolve Intrinsic Track Sizes
 
-    // The track sizing algorithm requires us to iterate through the items in ascendeding order of the number of
-    // tracks they span (first items that span 1 track, then items that span 2 tracks, etc).
-    // To avoid having to do multiple iterations of the items, we pre-sort them into this order.
-    items.sort_by(cmp_by_cross_flex_then_span_then_start(axis));
-
     // Compute an additional amount to add to each spanned gutter when computing item's estimated size in the
     // in the opposite axis based on the alignment, container size, and estimated track sizes in that axis
     let gutter_alignment_adjustment = compute_alignment_gutter_adjustment(
@@ -339,6 +431,78 @@ fn initialize_track_sizes(axis_tracks: &mut [GridTrack], axis_inner_node_size: O
     }
 }
 
+/// 11.5.1 Shim baseline-aligned items so their intrinsic size contributions reflect their baseline alignment.
+fn resolve_item_baselines(
+    tree: &mut impl LayoutTree,
+    axis: AbstractAxis,
+    items: &mut [GridItem],
+    inner_node_size: Size<Option<f32>>,
+) {
+    // Sort items by track in the other axis (row) start position so that we can iterate items in groups which
+    // are in the same track in the other axis (row)
+    let other_axis = axis.other();
+    items.sort_by_key(|item| item.placement(other_axis).start);
+
+    // Iterate over grid rows
+    let mut remaining_items = &mut items[0..];
+    while !remaining_items.is_empty() {
+        // Get the row index of the current row
+        let current_row = remaining_items[0].placement(other_axis).start;
+
+        // Find the item index of the first item that is in a different row (or None if we've reached the end of the list)
+        let next_row_first_item =
+            remaining_items.iter().position(|item| item.placement(other_axis).start != current_row);
+
+        // Use this index to split the `remaining_items` slice in two slices:
+        //    - A `row_items` slice containing the items (that start) in the current row
+        //    - A new `remaining_items` consisting of the remainder of the `remaining_items` slice
+        //      that hasn't been split off into `row_items
+        let row_items = if let Some(index) = next_row_first_item {
+            let (row_items, tail) = remaining_items.split_at_mut(index);
+            remaining_items = tail;
+            row_items
+        } else {
+            let row_items = remaining_items;
+            remaining_items = &mut [];
+            row_items
+        };
+
+        // Count how many items in *this row* are baseline aligned
+        // If a row has one or zero items participating in baseline alignment then baseline alignment is a no-op
+        // for those items and we skip further computations for that row
+        let row_baseline_item_count = row_items.iter().filter(|item| item.align_self == AlignSelf::Baseline).count();
+        if row_baseline_item_count <= 1 {
+            continue;
+        }
+
+        // Compute the baselines of all items in the row
+        for item in row_items.iter_mut() {
+            let measured_size_and_baselines = GenericAlgorithm::perform_layout(
+                tree,
+                item.node,
+                Size::NONE,
+                inner_node_size,
+                Size::MIN_CONTENT,
+                SizingMode::InherentSize,
+            );
+
+            let baseline = measured_size_and_baselines.first_baselines.y;
+            let height = measured_size_and_baselines.size.height;
+
+            item.baseline = Some(baseline.unwrap_or(height) + item.margin.top.resolve_or_zero(inner_node_size.width));
+        }
+
+        // Compute the max baseline of all items in the row
+        let row_max_baseline =
+            row_items.iter().map(|item| item.baseline.unwrap_or(0.0)).max_by(|a, b| a.total_cmp(b)).unwrap();
+
+        // Compute the baseline shim for each item in the row
+        for item in row_items.iter_mut() {
+            item.baseline_shim = row_max_baseline - item.baseline.unwrap_or(0.0);
+        }
+    }
+}
+
 /// 11.5 Resolve Intrinsic Track Sizes
 #[allow(clippy::too_many_arguments)]
 fn resolve_intrinsic_track_sizes(
@@ -352,18 +516,19 @@ fn resolve_intrinsic_track_sizes(
     get_track_size_estimate: impl Fn(&GridTrack, Option<f32>) -> Option<f32>,
 ) {
     // Step 1. Shim baseline-aligned items so their intrinsic size contributions reflect their baseline alignment.
-    // TODO: we do not yet support baseline alignment for CSS Grid
-
-    // Step 2. We skip Step 2 as it is noted that:
-    //
-    //    This step is a simplification of the steps below for handling spanning items, and should yield
-    //    the same behavior as running those instructions on items with a span of 1.
-    //
-    // We choose this alternative of running Step 3 on items with a span of 1 as we need to write the code for this anyway.
-
-    // Step 3 and Step 4
-    // 3. Iterate over items that don't cross a flex track. Items should have already been sorted in ascending order
-    // of the number of tracks they cross.
+
+    // Already done at this point. See resolve_item_baselines function.
+
+    // Step 2.
+
+    // The track sizing algorithm requires us to iterate through the items in ascendeding order of the number of
+    // tracks they span (first items that span 1 track, then items that span 2 tracks, etc).
+    // To avoid having to do multiple iterations of the items, we pre-sort them into this order.
+    items.sort_by(cmp_by_cross_flex_then_span_then_start(axis));
+
+    // Step 2, Step 3 and Step 4
+    // 2 & 3. Iterate over items that don't cross a flex track. Items should have already been sorted in ascending order
+    // of the number of tracks they span. Step 2 is the 1 track case and has an optimised implementation
     // 4. Next, repeat the previous step instead considering (together, rather than grouped by span size) all items
     // that do span a track with a flexible sizing function while
 
@@ -372,106 +537,98 @@ fn resolve_intrinsic_track_sizes(
     // to the min-content contribution—but can differ in some cases, see §6.6 Automatic Minimum Size of Grid Items.
     // Also, minimum contribution <= min-content contribution <= max-content contribution.
 
-    /// This struct captures a bunch of variables which are used to compute the intrinsic sizes of children so that those variables
-    /// don't have to be passed around all over the place below. It then has methods that implement the intrinsic sizing computations
-    struct IntrisicSizeMeasurer<'tree, 'oat, Tree, EstimateFunction>
-    where
-        Tree: LayoutTree,
-        EstimateFunction: Fn(&GridTrack, Option<f32>) -> Option<f32>,
-    {
-        /// The layout tree
-        tree: &'tree mut Tree,
-        /// The tracks in the opposite axis to the one we are currently sizing
-        other_axis_tracks: &'oat [GridTrack],
-        /// A function that computes an estimate of an other-axis track's size which is passed to
-        /// the child size measurement functions
-        get_track_size_estimate: EstimateFunction,
-        /// The axis we are currently sizing
-        axis: AbstractAxis,
-        /// The available grid space
-        inner_node_size: Size<Option<f32>>,
-    }
+    let axis_inner_node_size = inner_node_size.get(axis);
+    let mut item_sizer =
+        IntrisicSizeMeasurer { tree, other_axis_tracks, axis, inner_node_size, get_track_size_estimate };
 
-    impl<'tree, 'oat, Tree, EstimateFunction> IntrisicSizeMeasurer<'tree, 'oat, Tree, EstimateFunction>
-    where
-        Tree: LayoutTree,
-        EstimateFunction: Fn(&GridTrack, Option<f32>) -> Option<f32>,
-    {
-        /// Compute the known_dimensions to be passed to the child sizing functions
-        /// These are estimates based on either the max track sizing function or the provisional base size in the opposite
-        /// axis to the one currently being sized.
-        /// https://www.w3.org/TR/css-grid-1/#algo-overview
-        #[inline(always)]
-        fn known_dimensions(&self, item: &mut GridItem) -> Size<Option<f32>> {
-            item.known_dimensions_cached(
-                self.axis,
-                self.other_axis_tracks,
-                self.inner_node_size.get(self.axis.other()),
-                &self.get_track_size_estimate,
-            )
-        }
+    let mut batched_item_iterator = ItemBatcher::new(axis);
+    while let Some((batch, is_flex)) = batched_item_iterator.next(items) {
+        // 2. Size tracks to fit non-spanning items: For each track with an intrinsic track sizing function and not a flexible sizing function,
+        // consider the items in it with a span of 1:
+        let batch_span = batch[0].placement(axis).span();
+        if !is_flex && batch_span == 1 {
+            for item in batch.iter_mut() {
+                let track_index = item.placement_indexes(axis).start + 1;
+                let track = &axis_tracks[track_index as usize];
 
-        /// Compute the item's resolved margins for size contributions. Horizontal percentage margins always resolve
-        /// to zero if the container size is indefinite as otherwise this would introduce a cyclic dependency.
-        #[inline(always)]
-        fn margins_axis_sums(&self, item: &mut GridItem) -> Size<f32> {
-            let parent_width = self.inner_node_size.width;
-            Rect {
-                left: item.margin.left.resolve_or_zero(Some(0.0)),
-                right: item.margin.right.resolve_or_zero(Some(0.0)),
-                top: item.margin.top.resolve_or_zero(parent_width),
-                bottom: item.margin.bottom.resolve_or_zero(parent_width),
+                // Handle base sizes
+                let new_base_size = match track.min_track_sizing_function {
+                    MinTrackSizingFunction::MinContent => {
+                        f32_max(track.base_size, item_sizer.min_content_contribution(item))
+                    }
+                    // If the container size is indefinite and has not yet been resolved then percentage sized
+                    // tracks should be treated as min-content (this matches Chrome's behaviour and seems sensible)
+                    MinTrackSizingFunction::Fixed(LengthPercentage::Percent(_)) => {
+                        if axis_inner_node_size.is_none() {
+                            f32_max(track.base_size, item_sizer.min_content_contribution(item))
+                        } else {
+                            track.base_size
+                        }
+                    }
+                    MinTrackSizingFunction::MaxContent => {
+                        f32_max(track.base_size, item_sizer.max_content_contribution(item))
+                    }
+                    MinTrackSizingFunction::Auto => {
+                        let space = match axis_available_grid_space {
+                            AvailableSpace::MinContent | AvailableSpace::MaxContent => {
+                                let axis_minimum_size = item_sizer.minimum_contribution(item, axis_tracks);
+                                let axis_min_content_size = item_sizer.min_content_contribution(item);
+                                let limit = track.max_track_sizing_function.definite_limit(axis_inner_node_size);
+                                axis_min_content_size.maybe_min(limit).max(axis_minimum_size)
+                            }
+                            AvailableSpace::Definite(_) => item_sizer.minimum_contribution(item, axis_tracks),
+                        };
+                        f32_max(track.base_size, space)
+                    }
+                    MinTrackSizingFunction::Fixed(_) => {
+                        // Do nothing as it's not an intrinsic track sizing function
+                        track.base_size
+                    }
+                };
+                let track = &mut axis_tracks[track_index as usize];
+                track.base_size = new_base_size;
+
+                // Handle growth limits
+                if let MaxTrackSizingFunction::FitContent(_) = track.max_track_sizing_function {
+                    let fit_content_limit = track.fit_content_limit(axis_inner_node_size);
+                    let min_content_contribution = item_sizer.min_content_contribution(item);
+                    let max_content_contribution =
+                        f32_min(item_sizer.max_content_contribution(item), fit_content_limit);
+                    track.growth_limit_planned_increase =
+                        f32_max(track.growth_limit_planned_increase, min_content_contribution);
+                    track.growth_limit_planned_increase =
+                        f32_max(track.growth_limit_planned_increase, max_content_contribution);
+                } else if track.max_track_sizing_function.is_max_content_alike() {
+                    track.growth_limit_planned_increase =
+                        f32_max(track.growth_limit_planned_increase, item_sizer.min_content_contribution(item));
+                    track.growth_limit_planned_increase =
+                        f32_max(track.growth_limit_planned_increase, item_sizer.max_content_contribution(item));
+                } else if track.max_track_sizing_function.definite_value(axis_inner_node_size).is_none() {
+                    // If the container size is indefinite and has not yet been resolved then percentage sized
+                    // tracks should be treated as min-content (this matches Chrome's behaviour and seems sensible)
+                    track.growth_limit_planned_increase =
+                        f32_max(track.growth_limit_planned_increase, item_sizer.min_content_contribution(item));
+                }
             }
-            .sum_axes()
-        }
 
-        /// Retrieve the item's min content contribution from the cache or compute it using the provided parameters
-        #[inline(always)]
-        fn min_content_contribution(&mut self, item: &mut GridItem) -> f32 {
-            let known_dimensions = self.known_dimensions(item);
-            let margin_axis_sums = self.margins_axis_sums(item);
-            let contribution =
-                item.min_content_contribution_cached(self.axis, self.tree, known_dimensions, self.inner_node_size);
-            contribution + margin_axis_sums.get(self.axis)
-        }
-
-        /// Retrieve the item's max content contribution from the cache or compute it using the provided parameters
-        #[inline(always)]
-        fn max_content_contribution(&mut self, item: &mut GridItem) -> f32 {
-            let known_dimensions = self.known_dimensions(item);
-            let margin_axis_sums = self.margins_axis_sums(item);
-            let contribution =
-                item.max_content_contribution_cached(self.axis, self.tree, known_dimensions, self.inner_node_size);
-            contribution + margin_axis_sums.get(self.axis)
-        }
+            for track in axis_tracks.iter_mut() {
+                if track.growth_limit_planned_increase > 0.0 {
+                    track.growth_limit = if track.growth_limit == f32::INFINITY {
+                        track.growth_limit_planned_increase
+                    } else {
+                        f32_max(track.growth_limit, track.growth_limit_planned_increase)
+                    };
+                }
+                track.infinitely_growable = false;
+                track.growth_limit_planned_increase = 0.0;
+                if track.growth_limit < track.base_size {
+                    track.growth_limit = track.base_size;
+                }
+            }
 
-        /// The minimum contribution of an item is the smallest outer size it can have.
-        /// Specifically:
-        ///   - If the item’s computed preferred size behaves as auto or depends on the size of its containing block in the relevant axis:
-        ///     Its minimum contribution is the outer size that would result from assuming the item’s used minimum size as its preferred size;
-        ///   - Else the item’s minimum contribution is its min-content contribution.
-        /// Because the minimum contribution often depends on the size of the item’s content, it is considered a type of intrinsic size contribution.
-        #[inline(always)]
-        fn minimum_contribution(&mut self, item: &mut GridItem, axis_tracks: &[GridTrack]) -> f32 {
-            let known_dimensions = self.known_dimensions(item);
-            let margin_axis_sums = self.margins_axis_sums(item);
-            let contribution = item.minimum_contribution_cached(
-                self.tree,
-                self.axis,
-                axis_tracks,
-                known_dimensions,
-                self.inner_node_size,
-            );
-            contribution + margin_axis_sums.get(self.axis)
+            continue;
         }
-    }
 
-    let axis_inner_node_size = inner_node_size.get(axis);
-    let mut item_sizer =
-        IntrisicSizeMeasurer { tree, other_axis_tracks, axis, inner_node_size, get_track_size_estimate };
-
-    let mut batched_item_iterator = ItemBatcher::new(axis);
-    while let Some((batch, is_flex)) = batched_item_iterator.next(items) {
         // 1. For intrinsic minimums:
         // First increase the base size of tracks with an intrinsic min track sizing function
         let has_intrinsic_min_track_sizing_function =
@@ -609,8 +766,6 @@ fn resolve_intrinsic_track_sizes(
             // 6. For max-content maximums: Lastly continue to increase the growth limit of tracks with a max track sizing function of max-content
             // by distributing extra space as needed to account for these items' max-content contributions. However, limit the growth of any
             // fit-content() tracks by their fit-content() argument.
-            let has_max_content_max_track_sizing_function =
-                |track: &GridTrack| track.max_track_sizing_function.is_max_content_alike();
             for item in batch.iter_mut() {
                 let axis_max_content_size = item_sizer.max_content_contribution(item);
                 let space = axis_max_content_size;
@@ -619,7 +774,7 @@ fn resolve_intrinsic_track_sizes(
                     distribute_item_space_to_growth_limit(
                         space,
                         tracks,
-                        has_max_content_max_track_sizing_function,
+                        |track: &GridTrack| track.max_track_sizing_function.is_max_content_alike(),
                         inner_node_size.get(axis),
                     );
                 }
diff --git a/src/compute/grid/types/grid_item.rs b/src/compute/grid/types/grid_item.rs
index 82d7a9ab9..9557522e2 100644
--- a/src/compute/grid/types/grid_item.rs
+++ b/src/compute/grid/types/grid_item.rs
@@ -8,7 +8,9 @@ use crate::layout::SizingMode;
 use crate::node::Node;
 use crate::prelude::LayoutTree;
 use crate::resolve::MaybeResolve;
-use crate::style::{LengthPercentageAuto, MaxTrackSizingFunction, MinTrackSizingFunction, Style};
+use crate::style::{
+    AlignItems, AlignSelf, LengthPercentageAuto, MaxTrackSizingFunction, MinTrackSizingFunction, Style,
+};
 use crate::style_helpers::*;
 use core::ops::Range;
 
@@ -33,6 +35,13 @@ pub(in super::super) struct GridItem {
 
     /// The item's margin style
     pub margin: Rect<LengthPercentageAuto>,
+    /// The item's align_self property, or the parent's align_items property is not set
+    pub align_self: AlignSelf,
+    /// The items first baseline (horizontal)
+    pub baseline: Option<f32>,
+    /// Shim for baseline alignment that acts like an extra top margin
+    /// TODO: Support last baseline and vertical text baselines
+    pub baseline_shim: f32,
 
     /// The item's definite row-start and row-end (same as `row` field, except in a different coordinate system)
     /// (as indexes into the Vec<GridTrack> stored in a grid's AbstractAxisTracks)
@@ -68,6 +77,7 @@ impl GridItem {
         col_span: Line<OriginZeroLine>,
         row_span: Line<OriginZeroLine>,
         style: &Style,
+        parent_align_items: AlignItems,
         source_order: u16,
     ) -> Self {
         GridItem {
@@ -76,6 +86,9 @@ impl GridItem {
             row: row_span,
             column: col_span,
             margin: style.margin,
+            align_self: style.align_self.unwrap_or(parent_align_items),
+            baseline: None,
+            baseline_shim: 0.0,
             row_indexes: Line { start: 0, end: 0 }, // Properly initialised later
             column_indexes: Line { start: 0, end: 0 }, // Properly initialised later
             crosses_flexible_row: false,            // Properly initialised later
diff --git a/test_fixtures/grid_align_items_baseline.html b/test_fixtures/grid_align_items_baseline.html
new file mode 100644
index 000000000..85f6171a0
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display:grid;width: 100px; height: 100px; align-items: baseline;">
+  <div style="display:grid;width: 50px; height: 50px;"></div>
+  <div style="display:grid;width: 50px; height: 20px;"></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_child.html b/test_fixtures/grid_align_items_baseline_child.html
new file mode 100644
index 000000000..2c848c042
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_child.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display:grid;width: 100px; height: 100px;align-items: baseline;">
+  <div style="display:grid;width: 50px; height: 50px;"></div>
+  <div style="display:grid;width: 50px; height: 20px;">
+    <div style="display:grid;width: 50px; height: 10px;"></div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_child_margin.html b/test_fixtures/grid_align_items_baseline_child_margin.html
new file mode 100644
index 000000000..a0303a20a
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_child_margin.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display:grid;width: 100px; height: 100px; align-items: baseline;">
+  <div style="display:grid;width: 50px; height: 50px;margin: 5px;"></div>
+  <div style="display:grid;width: 50px; height: 20px;">
+    <div style="display:grid;width: 50px; height: 10px;margin: 5px;"></div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_child_margin_percent.html b/test_fixtures/grid_align_items_baseline_child_margin_percent.html
new file mode 100644
index 000000000..8502cc25e
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_child_margin_percent.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display:grid;width: 100px; height: 100px;align-items: baseline;">
+  <div style="display:grid;width: 50px; height: 50px;margin: 5%;"></div>
+  <div style="display:grid;width: 50px; height: 20px;">
+    <div style="display:grid;width: 50px; height: 10px;margin: 1%;"></div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_child_multiline.html b/test_fixtures/grid_align_items_baseline_child_multiline.html
new file mode 100644
index 000000000..73a019d8f
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_child_multiline.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display:grid;width: 100px; align-items: baseline;">
+  <div style="display:grid;width: 50px; height: 60px;"></div>
+  <div style="display:grid;grid-template-columns: auto auto;width: 50px; flex-wrap: wrap;">
+    <div style="display:grid;width: 25px; height: 20px;"></div>
+    <div style="display:grid;width: 25px; height: 10px;"></div>
+    <div style="display:grid;width: 25px; height: 20px;"></div>
+    <div style="display:grid;width: 25px; height: 10px;"></div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_child_multiline_no_override_on_secondline.html b/test_fixtures/grid_align_items_baseline_child_multiline_no_override_on_secondline.html
new file mode 100644
index 000000000..3d0907dcd
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_child_multiline_no_override_on_secondline.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display:grid;width: 100px; height: 100px;align-items: baseline;">
+  <div style="display:grid;width: 50px; height: 60px;"></div>
+  <div style="display:grid;grid-template-columns: auto auto;width: 50px; height: 25px;">
+    <div style="display:grid;width: 25px; height: 20px;"></div>
+    <div style="display:grid;width: 25px; height: 10px;"></div>
+    <div style="display:grid;width: 25px; height: 20px;"></div>
+    <div style="display:grid;width: 25px; height: 10px;align-self:baseline;"></div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_child_multiline_override.html b/test_fixtures/grid_align_items_baseline_child_multiline_override.html
new file mode 100644
index 000000000..54f975fd9
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_child_multiline_override.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display:grid;width: 100px; height: 100px;align-items: baseline;">
+  <div style="display:grid;width: 50px; height: 60px;"></div>
+  <div style="display:grid;rid-template-columns: auto auto;width: 50px; height: 25px;">
+    <div style="display:grid;width: 25px; height: 20px;"></div>
+    <div style="display:grid;width: 25px; height: 10px;align-self:baseline;"></div>
+    <div style="display:grid;width: 25px; height: 20px;"></div>
+    <div style="display:grid;width: 25px; height: 10px;align-self:baseline;"></div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_child_padding.html b/test_fixtures/grid_align_items_baseline_child_padding.html
new file mode 100644
index 000000000..44df378ba
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_child_padding.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display: grid;width: 100px; height: 100px; padding:5px; align-items: baseline;">
+  <div style="display: grid;width: 50px; height: 50px;"></div>
+  <div style="display: grid;width: 50px; height: 20px;padding:5px;">
+    <div style="display: grid;width: 50px; height: 10px;"></div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_child_top.html b/test_fixtures/grid_align_items_baseline_child_top.html
new file mode 100644
index 000000000..197d821d8
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_child_top.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display: grid;width: 100px; height: 100px;align-items: baseline;">
+  <div style="display: grid;width: 50px; height: 50px;top:10px;"></div>
+  <div style="display: grid;width: 50px; height: 20px;">
+    <div style="display: grid;width: 50px; height: 10px;"></div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_child_top2.html b/test_fixtures/grid_align_items_baseline_child_top2.html
new file mode 100644
index 000000000..7394b3bb1
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_child_top2.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display: grid;width: 100px; height: 100px;align-items: baseline;">
+  <div style="display: grid;width: 50px; height: 50px;"></div>
+  <div style="display: grid;width: 50px; height: 20px;top:5px">
+    <div style="display: grid;width: 50px; height: 10px;"></div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/xgrid_align_items_baseline_complex.html b/test_fixtures/grid_align_items_baseline_complex.html
similarity index 100%
rename from test_fixtures/xgrid_align_items_baseline_complex.html
rename to test_fixtures/grid_align_items_baseline_complex.html
diff --git a/test_fixtures/grid_align_items_baseline_double_nested_child.html b/test_fixtures/grid_align_items_baseline_double_nested_child.html
new file mode 100644
index 000000000..3cb9927f3
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_double_nested_child.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display: grid;width: 100px; height: 100px;align-items: baseline;">
+  <div style="display: grid;width: 50px; height: 50px;">
+    <div style="display: grid;width: 50px; height: 20px;"></div>
+  </div>
+  <div style="display: grid;width: 50px; height: 20px;">
+    <div style="display: grid;width: 50px; height: 15px;"></div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_multiline.html b/test_fixtures/grid_align_items_baseline_multiline.html
new file mode 100644
index 000000000..7d3ca4b22
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_multiline.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display: grid;grid-template-columns: auto auto;width: 100px; height: 100px; align-items: baseline;">
+  <div style="display: grid;width: 50px; height: 50px;"></div>
+  <div style="display: grid;width: 50px; height: 20px;">
+    <div style="display: grid;width: 50px; height: 10px;"></div>
+  </div>
+  <div style="display: grid;width: 50px; height: 20px;">
+    <div style="display: grid;width: 50px; height: 10px;"></div>
+  </div>
+  <div style="display: grid;width: 50px; height: 50px;"></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_multiline_column.html b/test_fixtures/grid_align_items_baseline_multiline_column.html
new file mode 100644
index 000000000..1ced23cff
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_multiline_column.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display: grid;grid-template-columns: auto auto;width: 100px; height: 100px;align-items: baseline;">
+  <div style="display: grid;width: 50px; height: 50px;"></div>
+  <div style="display: grid;width: 30px; height: 50px;">
+    <div style="display: grid;width: 20px; height: 20px;"></div>
+  </div>
+  <div style="display: grid;width: 40px; height: 70px;">
+    <div style="display: grid;width: 10px; height: 10px;"></div>
+  </div>
+  <div style="display: grid;width: 50px; height: 20px;"></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_multiline_row_and_column.html b/test_fixtures/grid_align_items_baseline_multiline_row_and_column.html
new file mode 100644
index 000000000..38e927966
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_multiline_row_and_column.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display: grid;grid-template-columns: auto auto;width: 100px; height: 100px;align-items: baseline;">
+  <div style="display: grid;width: 50px; height: 50px;"></div>
+  <div style="display: grid;width: 50px; height: 50px">
+    <div style="display: grid;width: 50px; height: 10px;"></div>
+  </div>
+  <div style="display: grid;width: 50px; height: 20px;">
+    <div style="display: grid;width: 50px; height: 10px;"></div>
+  </div>
+  <div style="display: grid;width: 50px; height: 20px;"></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_align_items_baseline_nested_column.html b/test_fixtures/grid_align_items_baseline_nested_column.html
new file mode 100644
index 000000000..3490e862f
--- /dev/null
+++ b/test_fixtures/grid_align_items_baseline_nested_column.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+<head/>
+<body>
+
+<div id="test-root" style="display: grid;width: 100px; height: 100px; align-items: baseline;">
+  <div style="display: grid;width: 50px; height: 60px;"></div>
+  <div style="display: grid;">
+    <div style="display: grid;width: 50px; height: 80px;">
+      <div style="display: grid;width: 50px; height: 30px;"></div>
+      <div style="display: grid;width: 50px; height: 40px;"></div>
+    </div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/tests/generated/grid_align_items_baseline.rs b/tests/generated/grid_align_items_baseline.rs
new file mode 100644
index 000000000..634288326
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline.rs
@@ -0,0 +1,60 @@
+#[test]
+fn grid_align_items_baseline() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 65f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 65f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_child.rs b/tests/generated/grid_align_items_baseline_child.rs
new file mode 100644
index 000000000..1560d275b
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_child.rs
@@ -0,0 +1,78 @@
+#[test]
+fn grid_align_items_baseline_child() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 65f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 65f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 50f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_child_margin.rs b/tests/generated/grid_align_items_baseline_child_margin.rs
new file mode 100644
index 000000000..21ce010f7
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_child_margin.rs
@@ -0,0 +1,90 @@
+#[test]
+fn grid_align_items_baseline_child_margin() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            margin: taffy::geometry::Rect {
+                left: taffy::style::LengthPercentageAuto::Points(5f32),
+                right: taffy::style::LengthPercentageAuto::Points(5f32),
+                top: taffy::style::LengthPercentageAuto::Points(5f32),
+                bottom: taffy::style::LengthPercentageAuto::Points(5f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            margin: taffy::geometry::Rect {
+                left: taffy::style::LengthPercentageAuto::Points(5f32),
+                right: taffy::style::LengthPercentageAuto::Points(5f32),
+                top: taffy::style::LengthPercentageAuto::Points(5f32),
+                bottom: taffy::style::LengthPercentageAuto::Points(5f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 5f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 5f32, location.x);
+    assert_eq!(location.y, 5f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 5f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 70f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 70f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 50f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 10f32, size.height);
+    assert_eq!(location.x, 5f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 5f32, location.x);
+    assert_eq!(location.y, 5f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 5f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_child_margin_percent.rs b/tests/generated/grid_align_items_baseline_child_margin_percent.rs
new file mode 100644
index 000000000..4c674213b
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_child_margin_percent.rs
@@ -0,0 +1,90 @@
+#[test]
+fn grid_align_items_baseline_child_margin_percent() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            margin: taffy::geometry::Rect {
+                left: taffy::style::LengthPercentageAuto::Percent(0.05f32),
+                right: taffy::style::LengthPercentageAuto::Percent(0.05f32),
+                top: taffy::style::LengthPercentageAuto::Percent(0.05f32),
+                bottom: taffy::style::LengthPercentageAuto::Percent(0.05f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            margin: taffy::geometry::Rect {
+                left: taffy::style::LengthPercentageAuto::Percent(0.01f32),
+                right: taffy::style::LengthPercentageAuto::Percent(0.01f32),
+                top: taffy::style::LengthPercentageAuto::Percent(0.01f32),
+                bottom: taffy::style::LengthPercentageAuto::Percent(0.01f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 5f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 5f32, location.x);
+    assert_eq!(location.y, 5f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 5f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 70f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 70f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 50f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 10f32, size.height);
+    assert_eq!(location.x, 1f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 1f32, location.x);
+    assert_eq!(location.y, 1f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 1f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_child_multiline.rs b/tests/generated/grid_align_items_baseline_child_multiline.rs
new file mode 100644
index 000000000..443e66978
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_child_multiline.rs
@@ -0,0 +1,119 @@
+#[test]
+fn grid_align_items_baseline_child_multiline() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(60f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node11 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node12 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node13 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                flex_wrap: taffy::style::FlexWrap::Wrap,
+                grid_template_columns: vec![auto(), auto()],
+                size: taffy::geometry::Size { width: taffy::style::Dimension::Points(50f32), height: auto() },
+                ..Default::default()
+            },
+            &[node10, node11, node12, node13],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size { width: taffy::style::Dimension::Points(100f32), height: auto() },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 60f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 60f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 60f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 60f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 25f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 25f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node11).unwrap();
+    assert_eq!(size.width, 25f32, "width of node {:?}. Expected {}. Actual {}", node11.data(), 25f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node11.data(), 10f32, size.height);
+    assert_eq!(location.x, 25f32, "x of node {:?}. Expected {}. Actual {}", node11.data(), 25f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node11.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node12).unwrap();
+    assert_eq!(size.width, 25f32, "width of node {:?}. Expected {}. Actual {}", node12.data(), 25f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node12.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node12.data(), 0f32, location.x);
+    assert_eq!(location.y, 20f32, "y of node {:?}. Expected {}. Actual {}", node12.data(), 20f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node13).unwrap();
+    assert_eq!(size.width, 25f32, "width of node {:?}. Expected {}. Actual {}", node13.data(), 25f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node13.data(), 10f32, size.height);
+    assert_eq!(location.x, 25f32, "x of node {:?}. Expected {}. Actual {}", node13.data(), 25f32, location.x);
+    assert_eq!(location.y, 20f32, "y of node {:?}. Expected {}. Actual {}", node13.data(), 20f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_child_multiline_no_override_on_secondline.rs b/tests/generated/grid_align_items_baseline_child_multiline_no_override_on_secondline.rs
new file mode 100644
index 000000000..2a3d7d037
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_child_multiline_no_override_on_secondline.rs
@@ -0,0 +1,125 @@
+#[test]
+fn grid_align_items_baseline_child_multiline_no_override_on_secondline() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(60f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node11 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node12 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node13 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            align_self: Some(taffy::style::AlignSelf::Baseline),
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_columns: vec![auto(), auto()],
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(25f32),
+                },
+                ..Default::default()
+            },
+            &[node10, node11, node12, node13],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 60f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 60f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 25f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 25f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 68f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 68f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 25f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 25f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node11).unwrap();
+    assert_eq!(size.width, 25f32, "width of node {:?}. Expected {}. Actual {}", node11.data(), 25f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node11.data(), 10f32, size.height);
+    assert_eq!(location.x, 25f32, "x of node {:?}. Expected {}. Actual {}", node11.data(), 25f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node11.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node12).unwrap();
+    assert_eq!(size.width, 25f32, "width of node {:?}. Expected {}. Actual {}", node12.data(), 25f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node12.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node12.data(), 0f32, location.x);
+    assert_eq!(location.y, 20f32, "y of node {:?}. Expected {}. Actual {}", node12.data(), 20f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node13).unwrap();
+    assert_eq!(size.width, 25f32, "width of node {:?}. Expected {}. Actual {}", node13.data(), 25f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node13.data(), 10f32, size.height);
+    assert_eq!(location.x, 25f32, "x of node {:?}. Expected {}. Actual {}", node13.data(), 25f32, location.x);
+    assert_eq!(location.y, 20f32, "y of node {:?}. Expected {}. Actual {}", node13.data(), 20f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_child_multiline_override.rs b/tests/generated/grid_align_items_baseline_child_multiline_override.rs
new file mode 100644
index 000000000..2b7675442
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_child_multiline_override.rs
@@ -0,0 +1,125 @@
+#[test]
+fn grid_align_items_baseline_child_multiline_override() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(60f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node11 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            align_self: Some(taffy::style::AlignSelf::Baseline),
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node12 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node13 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            align_self: Some(taffy::style::AlignSelf::Baseline),
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(25f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(25f32),
+                },
+                ..Default::default()
+            },
+            &[node10, node11, node12, node13],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 60f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 60f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 25f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 25f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 68f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 68f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 25f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 25f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node11).unwrap();
+    assert_eq!(size.width, 25f32, "width of node {:?}. Expected {}. Actual {}", node11.data(), 25f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node11.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node11.data(), 0f32, location.x);
+    assert_eq!(location.y, 20f32, "y of node {:?}. Expected {}. Actual {}", node11.data(), 20f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node12).unwrap();
+    assert_eq!(size.width, 25f32, "width of node {:?}. Expected {}. Actual {}", node12.data(), 25f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node12.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node12.data(), 0f32, location.x);
+    assert_eq!(location.y, 30f32, "y of node {:?}. Expected {}. Actual {}", node12.data(), 30f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node13).unwrap();
+    assert_eq!(size.width, 25f32, "width of node {:?}. Expected {}. Actual {}", node13.data(), 25f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node13.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node13.data(), 0f32, location.x);
+    assert_eq!(location.y, 50f32, "y of node {:?}. Expected {}. Actual {}", node13.data(), 50f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_child_padding.rs b/tests/generated/grid_align_items_baseline_child_padding.rs
new file mode 100644
index 000000000..e94c1625e
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_child_padding.rs
@@ -0,0 +1,90 @@
+#[test]
+fn grid_align_items_baseline_child_padding() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                padding: taffy::geometry::Rect {
+                    left: taffy::style::LengthPercentage::Points(5f32),
+                    right: taffy::style::LengthPercentage::Points(5f32),
+                    top: taffy::style::LengthPercentage::Points(5f32),
+                    bottom: taffy::style::LengthPercentage::Points(5f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                padding: taffy::geometry::Rect {
+                    left: taffy::style::LengthPercentage::Points(5f32),
+                    right: taffy::style::LengthPercentage::Points(5f32),
+                    top: taffy::style::LengthPercentage::Points(5f32),
+                    bottom: taffy::style::LengthPercentage::Points(5f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 5f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 5f32, location.x);
+    assert_eq!(location.y, 5f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 5f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, size.height);
+    assert_eq!(location.x, 5f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 5f32, location.x);
+    assert_eq!(location.y, 65f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 65f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 50f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 10f32, size.height);
+    assert_eq!(location.x, 5f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 5f32, location.x);
+    assert_eq!(location.y, 5f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 5f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_child_top.rs b/tests/generated/grid_align_items_baseline_child_top.rs
new file mode 100644
index 000000000..456596c46
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_child_top.rs
@@ -0,0 +1,84 @@
+#[test]
+fn grid_align_items_baseline_child_top() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            inset: taffy::geometry::Rect {
+                left: auto(),
+                right: auto(),
+                top: taffy::style::LengthPercentageAuto::Points(10f32),
+                bottom: auto(),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 10f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 10f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 65f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 65f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 50f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_child_top2.rs b/tests/generated/grid_align_items_baseline_child_top2.rs
new file mode 100644
index 000000000..0b8bc6ad9
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_child_top2.rs
@@ -0,0 +1,84 @@
+#[test]
+fn grid_align_items_baseline_child_top2() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                inset: taffy::geometry::Rect {
+                    left: auto(),
+                    right: auto(),
+                    top: taffy::style::LengthPercentageAuto::Points(5f32),
+                    bottom: auto(),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 70f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 70f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 50f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_complex.rs b/tests/generated/grid_align_items_baseline_complex.rs
new file mode 100644
index 000000000..c903c807f
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_complex.rs
@@ -0,0 +1,214 @@
+#[test]
+fn grid_align_items_baseline_complex() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(20f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Points(10f32) },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(20f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node20 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Points(10f32) },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(20f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node20],
+        )
+        .unwrap();
+    let node3 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(20f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node4 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(20f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node5 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(20f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node60 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Points(10f32) },
+            ..Default::default()
+        })
+        .unwrap();
+    let node6 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(20f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node60],
+        )
+        .unwrap();
+    let node70 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size { width: auto(), height: taffy::style::Dimension::Points(5f32) },
+            ..Default::default()
+        })
+        .unwrap();
+    let node7 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(20f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node70],
+        )
+        .unwrap();
+    let node8 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(20f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
+                grid_template_columns: vec![points(40f32), points(40f32), points(40f32)],
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(120f32),
+                    height: taffy::style::Dimension::Points(120f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1, node2, node3, node4, node5, node6, node7, node8],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 120f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 120f32, size.width);
+    assert_eq!(size.height, 120f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 120f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 20f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, size.height);
+    assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.x);
+    assert_eq!(location.y, 10f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 10f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+    assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 20f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 20f32, size.height);
+    assert_eq!(location.x, 80f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 80f32, location.x);
+    assert_eq!(location.y, 10f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 10f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node20).unwrap();
+    assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node20.data(), 0f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node20.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node20.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node20.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node3).unwrap();
+    assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node3.data(), 20f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 0f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node4).unwrap();
+    assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node4.data(), 20f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node4.data(), 20f32, size.height);
+    assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node5).unwrap();
+    assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node5.data(), 20f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node5.data(), 20f32, size.height);
+    assert_eq!(location.x, 80f32, "x of node {:?}. Expected {}. Actual {}", node5.data(), 80f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node6).unwrap();
+    assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node6.data(), 20f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node6.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node6.data(), 0f32, location.x);
+    assert_eq!(location.y, 90f32, "y of node {:?}. Expected {}. Actual {}", node6.data(), 90f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node60).unwrap();
+    assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node60.data(), 0f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node60.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node60.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node60.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node7).unwrap();
+    assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node7.data(), 20f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node7.data(), 20f32, size.height);
+    assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, location.x);
+    assert_eq!(location.y, 95f32, "y of node {:?}. Expected {}. Actual {}", node7.data(), 95f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node70).unwrap();
+    assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node70.data(), 0f32, size.width);
+    assert_eq!(size.height, 5f32, "height of node {:?}. Expected {}. Actual {}", node70.data(), 5f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node70.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node70.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node8).unwrap();
+    assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node8.data(), 20f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node8.data(), 20f32, size.height);
+    assert_eq!(location.x, 80f32, "x of node {:?}. Expected {}. Actual {}", node8.data(), 80f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node8.data(), 80f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_double_nested_child.rs b/tests/generated/grid_align_items_baseline_double_nested_child.rs
new file mode 100644
index 000000000..cbe9639af
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_double_nested_child.rs
@@ -0,0 +1,96 @@
+#[test]
+fn grid_align_items_baseline_double_nested_child() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node00 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node0 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(50f32),
+                },
+                ..Default::default()
+            },
+            &[node00],
+        )
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(15f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node00).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node00.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node00.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node00.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node00.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 65f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 65f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 50f32, size.width);
+    assert_eq!(size.height, 15f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 15f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_multiline.rs b/tests/generated/grid_align_items_baseline_multiline.rs
new file mode 100644
index 000000000..c8b85828b
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_multiline.rs
@@ -0,0 +1,127 @@
+#[test]
+fn grid_align_items_baseline_multiline() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node20 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node20],
+        )
+        .unwrap();
+    let node3 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                grid_template_columns: vec![auto(), auto()],
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1, node2, node3],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 20f32, size.height);
+    assert_eq!(location.x, 50f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 50f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+    assert_eq!(location.y, 100f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 100f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node20).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node20.data(), 50f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node20.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node20.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node20.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node3).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node3.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 50f32, size.height);
+    assert_eq!(location.x, 50f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 50f32, location.x);
+    assert_eq!(location.y, 60f32, "y of node {:?}. Expected {}. Actual {}", node3.data(), 60f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_multiline_column.rs b/tests/generated/grid_align_items_baseline_multiline_column.rs
new file mode 100644
index 000000000..e1ec0fc48
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_multiline_column.rs
@@ -0,0 +1,127 @@
+#[test]
+fn grid_align_items_baseline_multiline_column() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(20f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(30f32),
+                    height: taffy::style::Dimension::Points(50f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node20 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(10f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(40f32),
+                    height: taffy::style::Dimension::Points(70f32),
+                },
+                ..Default::default()
+            },
+            &[node20],
+        )
+        .unwrap();
+    let node3 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                grid_template_columns: vec![auto(), auto()],
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1, node2, node3],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 30f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 30f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.height);
+    assert_eq!(location.x, 50f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, location.x);
+    assert_eq!(location.y, 30f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 30f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 20f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+    assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.width);
+    assert_eq!(size.height, 70f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 70f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+    assert_eq!(location.y, 90f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 90f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node20).unwrap();
+    assert_eq!(size.width, 10f32, "width of node {:?}. Expected {}. Actual {}", node20.data(), 10f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node20.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node20.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node20.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node3).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node3.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 20f32, size.height);
+    assert_eq!(location.x, 50f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 50f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node3.data(), 80f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_multiline_row_and_column.rs b/tests/generated/grid_align_items_baseline_multiline_row_and_column.rs
new file mode 100644
index 000000000..26735b627
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_multiline_row_and_column.rs
@@ -0,0 +1,127 @@
+#[test]
+fn grid_align_items_baseline_multiline_row_and_column() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(50f32),
+                },
+                ..Default::default()
+            },
+            &[node10],
+        )
+        .unwrap();
+    let node20 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(10f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(20f32),
+                },
+                ..Default::default()
+            },
+            &[node20],
+        )
+        .unwrap();
+    let node3 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(20f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                grid_template_columns: vec![auto(), auto()],
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1, node2, node3],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.height);
+    assert_eq!(location.x, 50f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 50f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 20f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+    assert_eq!(location.y, 100f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 100f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node20).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node20.data(), 50f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node20.data(), 10f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node20.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node20.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node3).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node3.data(), 50f32, size.width);
+    assert_eq!(size.height, 20f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 20f32, size.height);
+    assert_eq!(location.x, 50f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 50f32, location.x);
+    assert_eq!(location.y, 90f32, "y of node {:?}. Expected {}. Actual {}", node3.data(), 90f32, location.y);
+}
diff --git a/tests/generated/grid_align_items_baseline_nested_column.rs b/tests/generated/grid_align_items_baseline_nested_column.rs
new file mode 100644
index 000000000..8c1be3550
--- /dev/null
+++ b/tests/generated/grid_align_items_baseline_nested_column.rs
@@ -0,0 +1,104 @@
+#[test]
+fn grid_align_items_baseline_nested_column() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(60f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node100 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(30f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node101 = taffy
+        .new_leaf(taffy::style::Style {
+            display: taffy::style::Display::Grid,
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(40f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node10 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(80f32),
+                },
+                ..Default::default()
+            },
+            &[node100, node101],
+        )
+        .unwrap();
+    let node1 = taffy
+        .new_with_children(
+            taffy::style::Style { display: taffy::style::Display::Grid, ..Default::default() },
+            &[node10],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                align_items: Some(taffy::style::AlignItems::Baseline),
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Points(100f32),
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 60f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 60f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 100f32, size.width);
+    assert_eq!(size.height, 80f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 80f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 60f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 60f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 50f32, size.width);
+    assert_eq!(size.height, 80f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 80f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node100).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node100.data(), 50f32, size.width);
+    assert_eq!(size.height, 30f32, "height of node {:?}. Expected {}. Actual {}", node100.data(), 30f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node100.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node100.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node101).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node101.data(), 50f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node101.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node101.data(), 0f32, location.x);
+    assert_eq!(location.y, 35f32, "y of node {:?}. Expected {}. Actual {}", node101.data(), 35f32, location.y);
+}
diff --git a/tests/generated/mod.rs b/tests/generated/mod.rs
index 73b8c371b..8ad7c04e8 100644
--- a/tests/generated/mod.rs
+++ b/tests/generated/mod.rs
@@ -362,6 +362,38 @@ mod grid_align_content_start;
 #[cfg(feature = "grid")]
 mod grid_align_content_start_with_padding_border;
 #[cfg(feature = "grid")]
+mod grid_align_items_baseline;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_margin;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_margin_percent;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_multiline;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_multiline_no_override_on_secondline;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_multiline_override;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_padding;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_top;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_child_top2;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_complex;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_double_nested_child;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_multiline;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_multiline_column;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_multiline_row_and_column;
+#[cfg(feature = "grid")]
+mod grid_align_items_baseline_nested_column;
+#[cfg(feature = "grid")]
 mod grid_align_items_sized_center;
 #[cfg(feature = "grid")]
 mod grid_align_items_sized_end;