tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

HTML 5544Rust 88Markdown 11TOML 91926 Definiciones

Fix grid track sizing for `fit-content(percentage)` and for items spanning percentage gaps (#335)

* Add tests for child spanning two max-content tracks with gaps between the tracks

* Recompute available_grid_space and node_inner_size after initial track sizing rounds WIP

* Suspect fix WIP

* Use computed column sizes for first iteration of row track size computation

* Don't limit the distribution of min-content sizes by the argument of a fit-content sizing function

* Simplify fit-content tests

* Resolve percentage track sizing function against node_inner_size rather than available_grid_space

* Add disabled percentage fit-content test

* Percentage fit content limits WIP

* Distribute growth_limit changes (broken)

* Simplify fit-content percent definite test

* Apply fit-content limit to growth limits

* When distributing space to growth_limit use base_size as affected property if growth_limit is infinite

* Add min_content and max_content variants of fit-content percent definite tests

* Add percent indefinite fit content tests

* Remove debug logs

* Remove commented out code

* Fix clippy lints

* Improve documentation of callback functions in distribute_item_space_to_base_size

* Remove useless code

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>

0596475afda99229de96976e73b2d637c78fdb8b · por Nico Burns · (hace 3 años) · padre 78fd9cc09 · ver el árbol en este commit

Delta semántico · 80

benches/generated/grid_fit_content_percent_definite_argument.rs

benches/generated/grid_fit_content_percent_definite_max_content.rs

benches/generated/grid_fit_content_percent_definite_min_content.rs

benches/generated/grid_fit_content_percent_indefinite_argument.rs

benches/generated/grid_fit_content_percent_indefinite_max_content.rs

benches/generated/grid_fit_content_percent_indefinite_min_content.rs

benches/generated/grid_fit_content_points_argument.rs

  • cambió por dentro fn compute pub

benches/generated/grid_fit_content_points_max_content.rs

  • cambió por dentro fn compute pub

benches/generated/grid_fit_content_points_min_content.rs

  • cambió por dentro fn compute pub

benches/generated/grid_max_content_single_item_span_2.rs

benches/generated/grid_max_content_single_item_span_2_gap_fixed.rs

benches/generated/grid_max_content_single_item_span_2_gap_percent_definite.rs

benches/generated/grid_max_content_single_item_span_2_gap_percent_indefinite.rs

src/compute/grid/mod.rs

  • cambió por dentro fn compute pub

src/compute/grid/track_sizing.rs

src/compute/grid/types/grid_item.rs

src/compute/grid/types/grid_track.rs

src/style/grid.rs

tests/generated/grid_fit_content_percent_definite_argument.rs

tests/generated/grid_fit_content_percent_definite_max_content.rs

tests/generated/grid_fit_content_percent_definite_min_content.rs

tests/generated/grid_fit_content_percent_indefinite_argument.rs

tests/generated/grid_fit_content_percent_indefinite_max_content.rs

tests/generated/grid_fit_content_percent_indefinite_min_content.rs

tests/generated/grid_fit_content_points_argument.rs

tests/generated/grid_fit_content_points_max_content.rs

tests/generated/grid_fit_content_points_min_content.rs

tests/generated/grid_max_content_single_item_span_2.rs

tests/generated/grid_max_content_single_item_span_2_gap_fixed.rs

tests/generated/grid_max_content_single_item_span_2_gap_percent_definite.rs

tests/generated/grid_max_content_single_item_span_2_gap_percent_indefinite.rs

46 archivos · +1541 −289

diff --git a/benches/generated/grid_fit_content_percent_definite_argument.rs b/benches/generated/grid_fit_content_percent_definite_argument.rs
new file mode 100644
index 000000000..e90221ba4
--- /dev/null
+++ b/benches/generated/grid_fit_content_percent_definite_argument.rs
@@ -0,0 +1,33 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style { ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(percent(0.5f32))],
+                size: taffy::geometry::Size { width: taffy::style::Dimension::Points(60f32), height: auto() },
+                ..Default::default()
+            },
+            &[node0],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_fit_content_percent_definite_max_content.rs b/benches/generated/grid_fit_content_percent_definite_max_content.rs
new file mode 100644
index 000000000..09403b3e0
--- /dev/null
+++ b/benches/generated/grid_fit_content_percent_definite_max_content.rs
@@ -0,0 +1,33 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style { ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(percent(0.5f32))],
+                size: taffy::geometry::Size { width: taffy::style::Dimension::Points(60f32), height: auto() },
+                ..Default::default()
+            },
+            &[node0],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_fit_content_percent_definite_min_content.rs b/benches/generated/grid_fit_content_percent_definite_min_content.rs
new file mode 100644
index 000000000..201685af7
--- /dev/null
+++ b/benches/generated/grid_fit_content_percent_definite_min_content.rs
@@ -0,0 +1,33 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style { ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(percent(0.5f32))],
+                size: taffy::geometry::Size { width: taffy::style::Dimension::Points(60f32), height: auto() },
+                ..Default::default()
+            },
+            &[node0],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_fit_content_percent_indefinite_argument.rs b/benches/generated/grid_fit_content_percent_indefinite_argument.rs
new file mode 100644
index 000000000..ba53e90c9
--- /dev/null
+++ b/benches/generated/grid_fit_content_percent_indefinite_argument.rs
@@ -0,0 +1,32 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style { ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH\u{200b}HH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(percent(0.5f32))],
+                ..Default::default()
+            },
+            &[node0],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_fit_content_percent_indefinite_max_content.rs b/benches/generated/grid_fit_content_percent_indefinite_max_content.rs
new file mode 100644
index 000000000..f1ecefc11
--- /dev/null
+++ b/benches/generated/grid_fit_content_percent_indefinite_max_content.rs
@@ -0,0 +1,32 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style { ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(percent(0.5f32))],
+                ..Default::default()
+            },
+            &[node0],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_fit_content_percent_indefinite_min_content.rs b/benches/generated/grid_fit_content_percent_indefinite_min_content.rs
new file mode 100644
index 000000000..ea8319a31
--- /dev/null
+++ b/benches/generated/grid_fit_content_percent_indefinite_min_content.rs
@@ -0,0 +1,32 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style { ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(percent(0.5f32))],
+                ..Default::default()
+            },
+            &[node0],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+}
diff --git a/benches/generated/grid_fit_content_points_argument.rs b/benches/generated/grid_fit_content_points_argument.rs
index a831b56e0..9bdc71bac 100644
--- a/benches/generated/grid_fit_content_points_argument.rs
+++ b/benches/generated/grid_fit_content_points_argument.rs
@@ -2,8 +2,7 @@ pub fn compute() {
     #[allow(unused_imports)]
     use taffy::prelude::*;
     let mut taffy = taffy::Taffy::new();
-    let node0 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node1 = taffy
+    let node0 = taffy
         .new_leaf_with_measure(
             taffy::style::Style { ..Default::default() },
             taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
@@ -18,22 +17,15 @@ pub fn compute() {
             }),
         )
         .unwrap();
-    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
     let node = taffy
         .new_with_children(
             taffy::style::Style {
                 display: taffy::style::Display::Grid,
-                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
-                grid_template_columns: vec![points(40f32), fit_content(points(30f32)), points(40f32)],
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(points(30f32))],
                 ..Default::default()
             },
-            &[node0, node1, node2, node3, node4, node5, node6, node7, node8],
+            &[node0],
         )
         .unwrap();
     taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
diff --git a/benches/generated/grid_fit_content_points_max_content.rs b/benches/generated/grid_fit_content_points_max_content.rs
index 9fff48fd5..3003459c2 100644
--- a/benches/generated/grid_fit_content_points_max_content.rs
+++ b/benches/generated/grid_fit_content_points_max_content.rs
@@ -2,8 +2,7 @@ pub fn compute() {
     #[allow(unused_imports)]
     use taffy::prelude::*;
     let mut taffy = taffy::Taffy::new();
-    let node0 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node1 = taffy
+    let node0 = taffy
         .new_leaf_with_measure(
             taffy::style::Style { ..Default::default() },
             taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
@@ -18,22 +17,15 @@ pub fn compute() {
             }),
         )
         .unwrap();
-    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
     let node = taffy
         .new_with_children(
             taffy::style::Style {
                 display: taffy::style::Display::Grid,
-                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
-                grid_template_columns: vec![points(40f32), fit_content(points(30f32)), points(40f32)],
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(points(30f32))],
                 ..Default::default()
             },
-            &[node0, node1, node2, node3, node4, node5, node6, node7, node8],
+            &[node0],
         )
         .unwrap();
     taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
diff --git a/benches/generated/grid_fit_content_points_min_content.rs b/benches/generated/grid_fit_content_points_min_content.rs
index cb4f1b256..ab0d6a14e 100644
--- a/benches/generated/grid_fit_content_points_min_content.rs
+++ b/benches/generated/grid_fit_content_points_min_content.rs
@@ -2,8 +2,7 @@ pub fn compute() {
     #[allow(unused_imports)]
     use taffy::prelude::*;
     let mut taffy = taffy::Taffy::new();
-    let node0 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node1 = taffy
+    let node0 = taffy
         .new_leaf_with_measure(
             taffy::style::Style { ..Default::default() },
             taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
@@ -18,22 +17,15 @@ pub fn compute() {
             }),
         )
         .unwrap();
-    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
     let node = taffy
         .new_with_children(
             taffy::style::Style {
                 display: taffy::style::Display::Grid,
-                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
-                grid_template_columns: vec![points(40f32), fit_content(points(30f32)), points(40f32)],
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(points(30f32))],
                 ..Default::default()
             },
-            &[node0, node1, node2, node3, node4, node5, node6, node7, node8],
+            &[node0],
         )
         .unwrap();
     taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
diff --git a/benches/generated/grid_max_content_single_item_span_2.rs b/benches/generated/grid_max_content_single_item_span_2.rs
new file mode 100644
index 000000000..aebe265b7
--- /dev/null
+++ b/benches/generated/grid_max_content_single_item_span_2.rs
@@ -0,0 +1,46 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node1 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                grid_column: taffy::geometry::Line {
+                    start: taffy::style::GridPlacement::Span(2u16),
+                    end: taffy::style::GridPlacement::Auto,
+                },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
+                grid_template_columns: vec![points(40f32), max_content(), max_content()],
+                ..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_max_content_single_item_span_2_gap_fixed.rs b/benches/generated/grid_max_content_single_item_span_2_gap_fixed.rs
new file mode 100644
index 000000000..3038aae25
--- /dev/null
+++ b/benches/generated/grid_max_content_single_item_span_2_gap_fixed.rs
@@ -0,0 +1,47 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node1 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                grid_column: taffy::geometry::Line {
+                    start: taffy::style::GridPlacement::Span(2u16),
+                    end: taffy::style::GridPlacement::Auto,
+                },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH\u{200b}HH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                gap: taffy::geometry::Size { width: taffy::style::LengthPercentage::Points(20f32), height: zero() },
+                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
+                grid_template_columns: vec![points(40f32), max_content(), max_content()],
+                ..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_max_content_single_item_span_2_gap_percent_definite.rs b/benches/generated/grid_max_content_single_item_span_2_gap_percent_definite.rs
new file mode 100644
index 000000000..626f9d086
--- /dev/null
+++ b/benches/generated/grid_max_content_single_item_span_2_gap_percent_definite.rs
@@ -0,0 +1,48 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node1 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                grid_column: taffy::geometry::Line {
+                    start: taffy::style::GridPlacement::Span(2u16),
+                    end: taffy::style::GridPlacement::Auto,
+                },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH\u{200b}HH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                gap: taffy::geometry::Size { width: taffy::style::LengthPercentage::Percent(0.2f32), height: zero() },
+                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
+                grid_template_columns: vec![points(40f32), max_content(), max_content()],
+                size: taffy::geometry::Size { width: taffy::style::Dimension::Points(100f32), height: auto() },
+                ..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_max_content_single_item_span_2_gap_percent_indefinite.rs b/benches/generated/grid_max_content_single_item_span_2_gap_percent_indefinite.rs
new file mode 100644
index 000000000..8d3fc67cb
--- /dev/null
+++ b/benches/generated/grid_max_content_single_item_span_2_gap_percent_indefinite.rs
@@ -0,0 +1,47 @@
+pub fn compute() {
+    #[allow(unused_imports)]
+    use taffy::prelude::*;
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node1 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                grid_column: taffy::geometry::Line {
+                    start: taffy::style::GridPlacement::Span(2u16),
+                    end: taffy::style::GridPlacement::Auto,
+                },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH\u{200b}HH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                gap: taffy::geometry::Size { width: taffy::style::LengthPercentage::Percent(0.2f32), height: zero() },
+                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
+                grid_template_columns: vec![points(40f32), max_content(), max_content()],
+                ..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/mod.rs b/benches/generated/mod.rs
index 3ae76d030..dcd569813 100644
--- a/benches/generated/mod.rs
+++ b/benches/generated/mod.rs
@@ -425,6 +425,18 @@ mod grid_basic_with_overflow;
 #[cfg(feature = "grid")]
 mod grid_basic_with_padding;
 #[cfg(feature = "grid")]
+mod grid_fit_content_percent_definite_argument;
+#[cfg(feature = "grid")]
+mod grid_fit_content_percent_definite_max_content;
+#[cfg(feature = "grid")]
+mod grid_fit_content_percent_definite_min_content;
+#[cfg(feature = "grid")]
+mod grid_fit_content_percent_indefinite_argument;
+#[cfg(feature = "grid")]
+mod grid_fit_content_percent_indefinite_max_content;
+#[cfg(feature = "grid")]
+mod grid_fit_content_percent_indefinite_min_content;
+#[cfg(feature = "grid")]
 mod grid_fit_content_points_argument;
 #[cfg(feature = "grid")]
 mod grid_fit_content_points_max_content;
@@ -507,6 +519,14 @@ mod grid_max_content_single_item_margin_fixed;
 #[cfg(feature = "grid")]
 mod grid_max_content_single_item_margin_percent;
 #[cfg(feature = "grid")]
+mod grid_max_content_single_item_span_2;
+#[cfg(feature = "grid")]
+mod grid_max_content_single_item_span_2_gap_fixed;
+#[cfg(feature = "grid")]
+mod grid_max_content_single_item_span_2_gap_percent_definite;
+#[cfg(feature = "grid")]
+mod grid_max_content_single_item_span_2_gap_percent_indefinite;
+#[cfg(feature = "grid")]
 mod grid_min_content_flex_column;
 #[cfg(feature = "grid")]
 mod grid_min_content_flex_row;
@@ -1096,6 +1116,18 @@ fn benchmark(c: &mut Criterion) {
             #[cfg(feature = "grid")]
             grid_basic_with_padding::compute();
             #[cfg(feature = "grid")]
+            grid_fit_content_percent_definite_argument::compute();
+            #[cfg(feature = "grid")]
+            grid_fit_content_percent_definite_max_content::compute();
+            #[cfg(feature = "grid")]
+            grid_fit_content_percent_definite_min_content::compute();
+            #[cfg(feature = "grid")]
+            grid_fit_content_percent_indefinite_argument::compute();
+            #[cfg(feature = "grid")]
+            grid_fit_content_percent_indefinite_max_content::compute();
+            #[cfg(feature = "grid")]
+            grid_fit_content_percent_indefinite_min_content::compute();
+            #[cfg(feature = "grid")]
             grid_fit_content_points_argument::compute();
             #[cfg(feature = "grid")]
             grid_fit_content_points_max_content::compute();
@@ -1178,6 +1210,14 @@ fn benchmark(c: &mut Criterion) {
             #[cfg(feature = "grid")]
             grid_max_content_single_item_margin_percent::compute();
             #[cfg(feature = "grid")]
+            grid_max_content_single_item_span_2::compute();
+            #[cfg(feature = "grid")]
+            grid_max_content_single_item_span_2_gap_fixed::compute();
+            #[cfg(feature = "grid")]
+            grid_max_content_single_item_span_2_gap_percent_definite::compute();
+            #[cfg(feature = "grid")]
+            grid_max_content_single_item_span_2_gap_percent_indefinite::compute();
+            #[cfg(feature = "grid")]
             grid_min_content_flex_column::compute();
             #[cfg(feature = "grid")]
             grid_min_content_flex_row::compute();
diff --git a/src/compute/grid/mod.rs b/src/compute/grid/mod.rs
index dc74c3920..c8f6c2939 100644
--- a/src/compute/grid/mod.rs
+++ b/src/compute/grid/mod.rs
@@ -154,7 +154,7 @@ pub fn compute(
     };
 
     let outer_node_size = size.maybe_clamp(min_size, max_size).or(parent_size.maybe_sub(margin.sum_axes()));
-    let inner_node_size = Size {
+    let mut inner_node_size = Size {
         width: outer_node_size.width.map(|space| space - padding.horizontal_axis_sum() - border.horizontal_axis_sum()),
         height: outer_node_size.height.map(|space| space - padding.vertical_axis_sum() - border.vertical_axis_sum()),
     };
@@ -192,6 +192,9 @@ pub fn compute(
             track.max_track_sizing_function.definite_value(available_space)
         },
     );
+    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());
+
     // Run track sizing algorithm for Block axis
     track_sizing_algorithm(
         tree,
@@ -203,10 +206,11 @@ pub fn compute(
         &mut rows,
         &mut columns,
         &mut items,
-        |track: &GridTrack, available_space: AvailableSpace| {
-            track.max_track_sizing_function.definite_value(available_space)
-        },
+        |track: &GridTrack, _| Some(track.base_size),
     );
+    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());
+
     // Re-run track sizing algorithm for Inline axis
     track_sizing_algorithm(
         tree,
@@ -220,6 +224,7 @@ pub fn compute(
         &mut items,
         |track: &GridTrack, _| Some(track.base_size),
     );
+
     // Re-run track sizing algorithm for Block axis
     track_sizing_algorithm(
         tree,
@@ -237,16 +242,12 @@ pub fn compute(
     // 6. Compute container size
     let resolved_style_size = known_dimensions.or(style.size.maybe_resolve(parent_size));
     let container_border_box = Size {
-        width: resolved_style_size.get(AbstractAxis::Inline).unwrap_or_else(|| {
-            columns.iter().map(|track| track.base_size).sum::<f32>()
-                + padding.horizontal_axis_sum()
-                + border.horizontal_axis_sum()
-        }),
-        height: resolved_style_size.get(AbstractAxis::Block).unwrap_or_else(|| {
-            rows.iter().map(|track| track.base_size).sum::<f32>()
-                + padding.vertical_axis_sum()
-                + border.vertical_axis_sum()
-        }),
+        width: resolved_style_size
+            .get(AbstractAxis::Inline)
+            .unwrap_or_else(|| initial_column_sum + padding.horizontal_axis_sum() + border.horizontal_axis_sum()),
+        height: resolved_style_size
+            .get(AbstractAxis::Block)
+            .unwrap_or_else(|| initial_row_sum + padding.vertical_axis_sum() + border.vertical_axis_sum()),
     };
     let container_content_box = Size {
         width: container_border_box.width - padding.horizontal_axis_sum() - border.horizontal_axis_sum(),
diff --git a/src/compute/grid/track_sizing.rs b/src/compute/grid/track_sizing.rs
index 2d9be1cac..65d64dd92 100644
--- a/src/compute/grid/track_sizing.rs
+++ b/src/compute/grid/track_sizing.rs
@@ -2,7 +2,7 @@
 //! https://www.w3.org/TR/css-grid-1/#layout-algorithm
 use super::types::{GridItem, GridTrack, TrackCounts};
 use crate::axis::AbstractAxis;
-use crate::geometry::Size;
+use crate::geometry::{Rect, Size};
 use crate::math::MaybeMath;
 use crate::prelude::LayoutTree;
 use crate::resolve::{MaybeResolve, ResolveOrZero};
@@ -176,7 +176,7 @@ pub(super) fn track_sizing_algorithm<Tree: LayoutTree>(
 ) {
     // 11.4 Initialise Track sizes
     // Initialize each track’s base size and growth limit.
-    initialize_track_sizes(axis_tracks, available_grid_space.get(axis));
+    initialize_track_sizes(axis_tracks, inner_node_size.get(axis));
 
     // 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
@@ -287,7 +287,7 @@ fn flush_planned_growth_limit_increases(tracks: &mut [GridTrack], set_infinitely
 
 /// 11.4 Initialise Track sizes
 /// Initialize each track’s base size and growth limit.
-fn initialize_track_sizes(axis_tracks: &mut [GridTrack], axis_available_grid_space: AvailableSpace) {
+fn initialize_track_sizes(axis_tracks: &mut [GridTrack], axis_inner_node_size: Option<f32>) {
     let last_track_idx = axis_tracks.len() - 1;
 
     // First and last grid lines are always zero-sized.
@@ -304,7 +304,7 @@ fn initialize_track_sizes(axis_tracks: &mut [GridTrack], axis_available_grid_spa
         //     Note: Indefinite lengths cannot occur, as they’re treated as auto.
         // - An intrinsic sizing function
         //     Use an initial base size of zero.
-        track.base_size = track.min_track_sizing_function.definite_value(axis_available_grid_space).unwrap_or(0.0);
+        track.base_size = track.min_track_sizing_function.definite_value(axis_inner_node_size.into()).unwrap_or(0.0);
 
         // For each track, if the track’s max track sizing function is:
         // - A fixed sizing function
@@ -314,7 +314,7 @@ fn initialize_track_sizes(axis_tracks: &mut [GridTrack], axis_available_grid_spa
         // - A flexible sizing function
         //     Use an initial growth limit of infinity.
         track.growth_limit =
-            track.max_track_sizing_function.definite_value(axis_available_grid_space).unwrap_or(f32::INFINITY);
+            track.max_track_sizing_function.definite_value(axis_inner_node_size.into()).unwrap_or(f32::INFINITY);
 
         // In all cases, if the growth limit is less than the base size, increase the growth limit to match the base size.
         if track.growth_limit < track.base_size {
@@ -364,7 +364,13 @@ fn resolve_intrinsic_track_sizes(
             &get_track_size_estimate,
         );
 
-        let margin = item.margin.map(|m| m.resolve_or_zero(available_grid_space.width.into_option())).sum_axes();
+        let margin = 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(available_grid_space.width.into_option()),
+            bottom: item.margin.bottom.resolve_or_zero(available_grid_space.width.into_option()),
+        }
+        .sum_axes();
 
         let min_content_size = item.min_content_contribution_cached(tree, known_dimensions, inner_node_size) + margin;
         let max_content_size = item.max_content_contribution_cached(tree, known_dimensions, inner_node_size) + margin;
@@ -397,7 +403,7 @@ fn resolve_intrinsic_track_sizes(
             // in place of their minimum contributions here.
             let space = match axis_available_grid_space {
                 AvailableSpace::MinContent | AvailableSpace::MaxContent => {
-                    let limit = item.spanned_fixed_track_limit(axis, axis_tracks, axis_available_grid_space);
+                    let limit = item.spanned_fixed_track_limit(axis, axis_tracks, inner_node_size.get(axis).into());
                     axis_min_content_size.maybe_min(limit).max(axis_minimum_size)
                 }
                 AvailableSpace::Definite(_) => axis_minimum_size,
@@ -410,6 +416,7 @@ fn resolve_intrinsic_track_sizes(
                     tracks,
                     has_intrinsic_min_track_sizing_function,
                     IntrinsicContributionType::Minimum,
+                    available_grid_space.get(axis),
                 );
             }
         }
@@ -433,6 +440,7 @@ fn resolve_intrinsic_track_sizes(
                     tracks,
                     has_min_or_max_content_min_track_sizing_function,
                     IntrinsicContributionType::Minimum,
+                    available_grid_space.get(axis),
                 );
             }
         }
@@ -450,7 +458,7 @@ fn resolve_intrinsic_track_sizes(
             };
             for item in batch.iter_mut() {
                 let (_, _, axis_max_content_size) = compute_item_sizes(item, axis_tracks);
-                let limit = item.spanned_fixed_track_limit(axis, axis_tracks, axis_available_grid_space);
+                let limit = item.spanned_fixed_track_limit(axis, axis_tracks, inner_node_size.get(axis).into());
                 let space = axis_max_content_size.maybe_min(limit);
                 let tracks = &mut axis_tracks[item.track_range_excluding_lines(axis)];
                 if space > 0.0 {
@@ -459,7 +467,8 @@ fn resolve_intrinsic_track_sizes(
                         space,
                         tracks,
                         has_auto_or_max_content_min_track_sizing_function,
-                        IntrinsicContributionType::Minimum,
+                        IntrinsicContributionType::Maximum,
+                        available_grid_space.get(axis),
                     );
                 }
             }
@@ -481,6 +490,7 @@ fn resolve_intrinsic_track_sizes(
                     tracks,
                     has_max_content_min_track_sizing_function,
                     IntrinsicContributionType::Maximum,
+                    available_grid_space.get(axis),
                 );
             }
         }
@@ -506,7 +516,12 @@ fn resolve_intrinsic_track_sizes(
                 let space = axis_min_content_size;
                 let tracks = &mut axis_tracks[item.track_range_excluding_lines(axis)];
                 if space > 0.0 {
-                    distribute_item_space_to_growth_limit(space, tracks, has_intrinsic_max_track_sizing_function);
+                    distribute_item_space_to_growth_limit(
+                        space,
+                        tracks,
+                        has_intrinsic_max_track_sizing_function,
+                        inner_node_size.get(axis),
+                    );
                 }
             }
             // Mark any tracks whose growth limit changed from infinite to finite in this step as infinitely growable for the next step.
@@ -516,13 +531,18 @@ fn resolve_intrinsic_track_sizes(
             // 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 =
-                move |track: &GridTrack| track.max_track_sizing_function == MaxTrackSizingFunction::MaxContent;
+                |track: &GridTrack| track.max_track_sizing_function.is_max_content_alike();
             for item in batch.iter_mut() {
                 let (_, _, axis_max_content_size) = compute_item_sizes(item, axis_tracks);
                 let space = axis_max_content_size;
                 let tracks = &mut axis_tracks[item.track_range_excluding_lines(axis)];
                 if space > 0.0 {
-                    distribute_item_space_to_growth_limit(space, tracks, has_max_content_max_track_sizing_function);
+                    distribute_item_space_to_growth_limit(
+                        space,
+                        tracks,
+                        has_max_content_max_track_sizing_function,
+                        inner_node_size.get(axis),
+                    );
                 }
             }
             // Mark any tracks whose growth limit changed from infinite to finite in this step as infinitely growable for the next step.
@@ -547,12 +567,25 @@ fn distribute_item_space_to_base_size(
     tracks: &mut [GridTrack],
     track_is_affected: impl Fn(&GridTrack) -> bool,
     intrinsic_contribution_type: IntrinsicContributionType,
+    axis_available_grid_space: AvailableSpace,
 ) {
     if is_flex {
         let filter = |track: &GridTrack| track.is_flexible() && track_is_affected(track);
-        distribute_item_space_to_base_size_inner(space, tracks, filter, intrinsic_contribution_type)
+        distribute_item_space_to_base_size_inner(
+            space,
+            tracks,
+            filter,
+            intrinsic_contribution_type,
+            axis_available_grid_space,
+        )
     } else {
-        distribute_item_space_to_base_size_inner(space, tracks, track_is_affected, intrinsic_contribution_type)
+        distribute_item_space_to_base_size_inner(
+            space,
+            tracks,
+            track_is_affected,
+            intrinsic_contribution_type,
+            axis_available_grid_space,
+        )
     }
 
     /// Inner function that doesn't account for differences due to distributing to flex items
@@ -562,6 +595,7 @@ fn distribute_item_space_to_base_size(
         tracks: &mut [GridTrack],
         track_is_affected: impl Fn(&GridTrack) -> bool,
         intrinsic_contribution_type: IntrinsicContributionType,
+        axis_available_grid_space: AvailableSpace,
     ) {
         // Skip this distribution if there is either
         //   - no space to distribute
@@ -570,6 +604,17 @@ fn distribute_item_space_to_base_size(
             return;
         }
 
+        // Define get_base_size function. This is passed to the distribute_space_up_to_limits helper function
+        // to indicate that it is the base size that is being distributed to.
+        let get_base_size = |track: &GridTrack| track.base_size;
+
+        // Define fit_content_limited_growth_limit function. This is passed to the distribute_space_up_to_limits
+        // helper function, and is used to compute the limit to distribute up to for each track.
+        // Wrapping the method on GridTrack is necessary in order to resolve percentage fit-content arguments.
+        let axis_available_grid_space_opt = axis_available_grid_space.into_option();
+        let fit_content_limited_growth_limit =
+            move |track: &GridTrack| track.fit_content_limited_growth_limit(axis_available_grid_space_opt);
+
         // 1. Find the space to distribute
         let track_sizes: f32 = tracks.iter().map(|track| track.base_size).sum();
         let extra_space: f32 = f32_max(0.0, space - track_sizes);
@@ -587,7 +632,8 @@ fn distribute_item_space_to_base_size(
             extra_space,
             tracks,
             &track_is_affected,
-            GridTrack::fit_content_limited_growth_limit,
+            get_base_size,
+            fit_content_limited_growth_limit,
         );
 
         // 3. Distribute remaining span beyond limits (if any)
@@ -613,7 +659,13 @@ fn distribute_item_space_to_base_size(
                 filter = (|_| true) as fn(&GridTrack) -> bool;
             }
 
-            distribute_space_up_to_limits(extra_space, tracks, filter, GridTrack::fit_content_limit);
+            // When distributing space beyond limits, the fit content limit applies to max-content sizes but not min-content sizes
+            let limit = match intrinsic_contribution_type {
+                IntrinsicContributionType::Minimum => &(|_: &GridTrack| f32::INFINITY) as &dyn Fn(&GridTrack) -> f32,
+                IntrinsicContributionType::Maximum => &fit_content_limited_growth_limit as &dyn Fn(&GridTrack) -> f32,
+            };
+
+            distribute_space_up_to_limits(extra_space, tracks, filter, get_base_size, limit);
         }
 
         // 4. For each affected track, if the track’s item-incurred increase is larger than the track’s planned increase
@@ -636,7 +688,15 @@ fn distribute_item_space_to_growth_limit(
     space: f32,
     tracks: &mut [GridTrack],
     track_is_affected: impl Fn(&GridTrack) -> bool,
+    axis_inner_node_size: Option<f32>,
 ) {
+    // Skip this distribution if there is either
+    //   - no space to distribute
+    //   - no affected tracks to distribute space to
+    if space == 0.0 || tracks.iter().filter(|track| track_is_affected(track)).count() == 0 {
+        return;
+    }
+
     // 1. Find the space to distribute
     let track_sizes: f32 = tracks
         .iter()
@@ -645,31 +705,46 @@ fn distribute_item_space_to_growth_limit(
     let extra_space: f32 = f32_max(0.0, space - track_sizes);
 
     // 2. Distribute space up to limits:
-    // 3. Distribute space beyond limits
-    // If space remains after all tracks are frozen, unfreeze and continue to distribute space to the item-incurred increase
-    // when handling any intrinsic growth limit: all affected tracks.
-    let number_of_growable_tracks =
-        tracks.iter().filter(|track| track_is_affected(track)).filter(|track| track.infinitely_growable).count();
+    // For growth limits the limit is either Infinity, or the growth limit itself. Which means that:
+    //   - If there are any tracks with infinite limits then all space will be distributed to those track(s).
+    //   - Otherwise no space will be distributed as part of this step
+    let number_of_growable_tracks = tracks
+        .iter()
+        .filter(|track| track_is_affected(track))
+        .filter(|track| {
+            track.infinitely_growable || track.fit_content_limited_growth_limit(axis_inner_node_size) == f32::INFINITY
+        })
+        .count();
     if number_of_growable_tracks > 0 {
         let item_incurred_increase = extra_space / number_of_growable_tracks as f32;
-        for track in
-            tracks.iter_mut().filter(|track| track_is_affected(track)).filter(|track| track.infinitely_growable)
-        {
-            if item_incurred_increase > track.growth_limit_planned_increase {
-                track.growth_limit_planned_increase = item_incurred_increase;
-            }
+        for track in tracks.iter_mut().filter(|track| track_is_affected(track)).filter(|track| {
+            track.infinitely_growable || track.fit_content_limited_growth_limit(axis_inner_node_size) == f32::INFINITY
+        }) {
+            track.item_incurred_increase = item_incurred_increase;
         }
     } else {
-        let number_of_affected_tracks = tracks.iter().filter(|track| track_is_affected(track)).count();
-        if number_of_affected_tracks > 0 {
-            let item_incurred_increase = extra_space / number_of_affected_tracks as f32;
-            for track in tracks.iter_mut().filter(|track| track_is_affected(track)) {
-                if item_incurred_increase > track.growth_limit_planned_increase {
-                    track.growth_limit_planned_increase = item_incurred_increase;
-                }
-            }
-        }
+        // 3. Distribute space beyond limits
+        // If space remains after all tracks are frozen, unfreeze and continue to distribute space to the item-incurred increase
+        // ...when handling any intrinsic growth limit: all affected tracks.
+        distribute_space_up_to_limits(
+            extra_space,
+            tracks,
+            track_is_affected,
+            |track| if track.growth_limit == f32::INFINITY { track.base_size } else { track.growth_limit },
+            move |track| track.fit_content_limit(axis_inner_node_size),
+        );
     };
+
+    // 4. For each affected track, if the track’s item-incurred increase is larger than the track’s planned increase
+    // set the track’s planned increase to that value.
+    for track in tracks.iter_mut() {
+        if track.item_incurred_increase > track.growth_limit_planned_increase {
+            track.growth_limit_planned_increase = track.item_incurred_increase;
+        }
+
+        // Reset the item_incurresed increase ready for the next space distribution
+        track.item_incurred_increase = 0.0;
+    }
 }
 
 /// 11.6 Maximise Tracks
@@ -680,7 +755,14 @@ fn maximise_tracks(axis: AbstractAxis, axis_tracks: &mut [GridTrack], available_
     if free_space == f32::INFINITY {
         axis_tracks.iter_mut().for_each(|track| track.base_size = track.growth_limit);
     } else if free_space > 0.0 {
-        distribute_space_up_to_limits(free_space, axis_tracks, |_| true, GridTrack::fit_content_limited_growth_limit);
+        let axis_available_grid_space = available_grid_space.get(axis).into_option();
+        distribute_space_up_to_limits(
+            free_space,
+            axis_tracks,
+            |_| true,
+            |track| track.base_size,
+            move |track: &GridTrack| track.fit_content_limited_growth_limit(axis_available_grid_space),
+        );
         for track in axis_tracks.iter_mut() {
             track.base_size += track.item_incurred_increase;
             track.item_incurred_increase = 0.0;
@@ -885,6 +967,7 @@ fn distribute_space_up_to_limits(
     space_to_distribute: f32,
     tracks: &mut [GridTrack],
     track_is_affected: impl Fn(&GridTrack) -> bool,
+    track_affected_property: impl Fn(&GridTrack) -> f32,
     track_limit: impl Fn(&GridTrack) -> f32,
 ) -> f32 {
     /// Define a small constant to avoid infinite loops due to rounding errors. Rather than stopping distributing
@@ -895,7 +978,7 @@ fn distribute_space_up_to_limits(
     while space_to_distribute > THRESHOLD {
         let number_of_growable_tracks = tracks
             .iter()
-            .filter(|track| track.base_size + track.item_incurred_increase < track_limit(track))
+            .filter(|track| track_affected_property(track) + track.item_incurred_increase < track_limit(track))
             .filter(|track| track_is_affected(track))
             .count();
 
@@ -906,9 +989,9 @@ fn distribute_space_up_to_limits(
         // Compute item-incurred increase for this iteration
         let min_increase_limit = tracks
             .iter()
-            .filter(|track| track.base_size + track.item_incurred_increase < track_limit(track))
+            .filter(|track| track_affected_property(track) + track.item_incurred_increase < track_limit(track))
             .filter(|track| track_is_affected(track))
-            .map(|track| track_limit(track) - track.base_size)
+            .map(|track| track_limit(track) - track_affected_property(track))
             .min_by(|a, b| a.total_cmp(b))
             .unwrap(); // We will never pass an empty track list to this function
         let iteration_item_incurred_increase =
@@ -917,7 +1000,7 @@ fn distribute_space_up_to_limits(
         for track in tracks
             .iter_mut()
             .filter(|track| track_is_affected(track))
-            .filter(|track| track.base_size + track.item_incurred_increase < track_limit(track))
+            .filter(|track| track_affected_property(track) + track.item_incurred_increase < track_limit(track))
         {
             track.item_incurred_increase += iteration_item_incurred_increase;
         }
diff --git a/src/compute/grid/types/grid_item.rs b/src/compute/grid/types/grid_item.rs
index 7eef6da71..36f0d5776 100644
--- a/src/compute/grid/types/grid_item.rs
+++ b/src/compute/grid/types/grid_item.rs
@@ -168,11 +168,11 @@ impl GridItem {
         let spanned_tracks = &axis_tracks[self.track_range_excluding_lines(axis)];
         let tracks_all_fixed = spanned_tracks
             .iter()
-            .all(|track| track.max_track_sizing_function.definite_value(axis_available_space).is_some());
+            .all(|track| track.max_track_sizing_function.definite_limit(axis_available_space).is_some());
         if tracks_all_fixed {
             let limit: f32 = spanned_tracks
                 .iter()
-                .map(|track| track.max_track_sizing_function.definite_value(axis_available_space).unwrap())
+                .map(|track| track.max_track_sizing_function.definite_limit(axis_available_space).unwrap())
                 .sum();
             Some(limit)
         } else {
diff --git a/src/compute/grid/types/grid_track.rs b/src/compute/grid/types/grid_track.rs
index c272f63b1..2c57b8e65 100644
--- a/src/compute/grid/types/grid_track.rs
+++ b/src/compute/grid/types/grid_track.rs
@@ -113,19 +113,23 @@ impl GridTrack {
 
     #[inline]
     /// Returns true if the track is flexible (has a Flex MaxTrackSizingFunction), else false.
-    pub fn fit_content_limit(&self) -> f32 {
+    pub fn fit_content_limit(&self, axis_available_grid_space: Option<f32>) -> f32 {
         match self.max_track_sizing_function {
             MaxTrackSizingFunction::FitContent(LengthPercentage::Points(limit)) => limit,
-            // TODO: properly support percentage fit-content values
-            MaxTrackSizingFunction::FitContent(LengthPercentage::Percent(_)) => f32::INFINITY,
+            MaxTrackSizingFunction::FitContent(LengthPercentage::Percent(fraction)) => {
+                match axis_available_grid_space {
+                    Some(space) => space * fraction,
+                    None => f32::INFINITY,
+                }
+            }
             _ => f32::INFINITY,
         }
     }
 
     #[inline]
     /// Returns true if the track is flexible (has a Flex MaxTrackSizingFunction), else false.
-    pub fn fit_content_limited_growth_limit(&self) -> f32 {
-        f32_min(self.growth_limit, self.fit_content_limit())
+    pub fn fit_content_limited_growth_limit(&self, axis_available_grid_space: Option<f32>) -> f32 {
+        f32_min(self.growth_limit, self.fit_content_limit(axis_available_grid_space))
     }
 
     #[inline]
diff --git a/src/style/grid.rs b/src/style/grid.rs
index 918f17482..cf89e057e 100644
--- a/src/style/grid.rs
+++ b/src/style/grid.rs
@@ -324,6 +324,24 @@ impl MaxTrackSizingFunction {
         }
     }
 
+    /// Resolve the maximum size of the track as defined by either:
+    ///     - A fixed track sizing function
+    ///     - A percentage track sizing function (with definite available space)
+    ///     - A fit-content sizing function with fixed argument
+    ///     - A fit-content sizing function with percentage argument (with definite available space)
+    /// All other kinds of track sizing function return None.
+    pub fn definite_limit(self, available_space: AvailableSpace) -> Option<f32> {
+        use MaxTrackSizingFunction::FitContent;
+        match self {
+            FitContent(LengthPercentage::Points(size)) => Some(size),
+            FitContent(LengthPercentage::Percent(fraction)) => match available_space {
+                AvailableSpace::Definite(available_size) => Some(fraction * available_size),
+                _ => None,
+            },
+            _ => self.definite_value(available_space),
+        }
+    }
+
     /// Resolve percentage values against the passed parent_size, returning Some(value)
     /// Non-percentage values always return None.
     #[inline(always)]
diff --git a/test_fixtures/grid_fit_content_percent_definite_argument.html b/test_fixtures/grid_fit_content_percent_definite_argument.html
new file mode 100644
index 000000000..19eb1d8b3
--- /dev/null
+++ b/test_fixtures/grid_fit_content_percent_definite_argument.html
@@ -0,0 +1,17 @@
+<!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: 60px; grid-template-columns: fit-content(50%);grid-template-rows: 40px">
+  <div>HH&ZeroWidthSpace;HH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_fit_content_percent_definite_max_content.html b/test_fixtures/grid_fit_content_percent_definite_max_content.html
new file mode 100644
index 000000000..72e5304c0
--- /dev/null
+++ b/test_fixtures/grid_fit_content_percent_definite_max_content.html
@@ -0,0 +1,17 @@
+<!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: 60px; grid-template-columns: fit-content(50%);grid-template-rows: 40px">
+  <div>HH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_fit_content_percent_definite_min_content.html b/test_fixtures/grid_fit_content_percent_definite_min_content.html
new file mode 100644
index 000000000..d13c3e31d
--- /dev/null
+++ b/test_fixtures/grid_fit_content_percent_definite_min_content.html
@@ -0,0 +1,17 @@
+<!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: 60px; grid-template-columns: fit-content(50%);grid-template-rows: 40px">
+  <div>HHHH&ZeroWidthSpace;HH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_fit_content_percent_indefinite_argument.html b/test_fixtures/grid_fit_content_percent_indefinite_argument.html
new file mode 100644
index 000000000..93c0d5670
--- /dev/null
+++ b/test_fixtures/grid_fit_content_percent_indefinite_argument.html
@@ -0,0 +1,17 @@
+<!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: fit-content(50%);grid-template-rows: 40px">
+  <div>HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_fit_content_percent_indefinite_max_content.html b/test_fixtures/grid_fit_content_percent_indefinite_max_content.html
new file mode 100644
index 000000000..3c7b13c1f
--- /dev/null
+++ b/test_fixtures/grid_fit_content_percent_indefinite_max_content.html
@@ -0,0 +1,17 @@
+<!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: fit-content(50%);grid-template-rows: 40px">
+  <div>HH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_fit_content_percent_indefinite_min_content.html b/test_fixtures/grid_fit_content_percent_indefinite_min_content.html
new file mode 100644
index 000000000..b29e72d4b
--- /dev/null
+++ b/test_fixtures/grid_fit_content_percent_indefinite_min_content.html
@@ -0,0 +1,17 @@
+<!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: fit-content(50%);grid-template-rows: 40px">
+  <div>HHHH&ZeroWidthSpace;HH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_fit_content_points_argument.html b/test_fixtures/grid_fit_content_points_argument.html
index a739e33be..1c407c38f 100644
--- a/test_fixtures/grid_fit_content_points_argument.html
+++ b/test_fixtures/grid_fit_content_points_argument.html
@@ -9,16 +9,8 @@
 <head/>
 <body>
 
-<div id="test-root" style="display: grid; grid-template-columns: 40px fit-content(30px) 40px;grid-template-rows: 40px 40px 40px">
-  <div></div>
+<div id="test-root" style="display: grid; grid-template-columns: fit-content(30px);grid-template-rows: 40px">
   <div>HH&ZeroWidthSpace;HH</div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
 </div>
 
 </body>
diff --git a/test_fixtures/grid_fit_content_points_max_content.html b/test_fixtures/grid_fit_content_points_max_content.html
index 6698442ad..3ae3fd05e 100644
--- a/test_fixtures/grid_fit_content_points_max_content.html
+++ b/test_fixtures/grid_fit_content_points_max_content.html
@@ -9,16 +9,8 @@
 <head/>
 <body>
 
-<div id="test-root" style="display: grid; grid-template-columns: 40px fit-content(30px) 40px;grid-template-rows: 40px 40px 40px">
-  <div></div>
+<div id="test-root" style="display: grid; grid-template-columns: fit-content(30px);grid-template-rows: 40px">
   <div>HH</div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
 </div>
 
 </body>
diff --git a/test_fixtures/grid_fit_content_points_min_content.html b/test_fixtures/grid_fit_content_points_min_content.html
index 455a0d639..7dcebf90a 100644
--- a/test_fixtures/grid_fit_content_points_min_content.html
+++ b/test_fixtures/grid_fit_content_points_min_content.html
@@ -9,16 +9,8 @@
 <head/>
 <body>
 
-<div id="test-root" style="display: grid; grid-template-columns: 40px fit-content(30px) 40px;grid-template-rows: 40px 40px 40px">
-  <div></div>
+<div id="test-root" style="display: grid; grid-template-columns: fit-content(30px);grid-template-rows: 40px">
   <div>HHHH&ZeroWidthSpace;HH</div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
-  <div></div>
 </div>
 
 </body>
diff --git a/test_fixtures/grid_max_content_single_item_span_2.html b/test_fixtures/grid_max_content_single_item_span_2.html
new file mode 100644
index 000000000..4f3684abe
--- /dev/null
+++ b/test_fixtures/grid_max_content_single_item_span_2.html
@@ -0,0 +1,25 @@
+<!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: 40px max-content max-content;grid-template-rows: 40px 40px 40px">
+  <div></div>
+  <div style="grid-column: span 2">HH&ZeroWidthSpace;HH</div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_max_content_single_item_span_2_gap_fixed.html b/test_fixtures/grid_max_content_single_item_span_2_gap_fixed.html
new file mode 100644
index 000000000..00a4e7dcb
--- /dev/null
+++ b/test_fixtures/grid_max_content_single_item_span_2_gap_fixed.html
@@ -0,0 +1,25 @@
+<!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: 40px max-content max-content;grid-template-rows: 40px 40px 40px; column-gap: 20px">
+  <div></div>
+  <div style="grid-column: span 2">HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH</div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_max_content_single_item_span_2_gap_percent_definite.html b/test_fixtures/grid_max_content_single_item_span_2_gap_percent_definite.html
new file mode 100644
index 000000000..242ec4f52
--- /dev/null
+++ b/test_fixtures/grid_max_content_single_item_span_2_gap_percent_definite.html
@@ -0,0 +1,25 @@
+<!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: 40px max-content max-content;grid-template-rows: 40px 40px 40px; column-gap: 20%;width:100px">
+  <div></div>
+  <div style="grid-column: span 2">HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH</div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_max_content_single_item_span_2_gap_percent_indefinite.html b/test_fixtures/grid_max_content_single_item_span_2_gap_percent_indefinite.html
new file mode 100644
index 000000000..be75d0b63
--- /dev/null
+++ b/test_fixtures/grid_max_content_single_item_span_2_gap_percent_indefinite.html
@@ -0,0 +1,25 @@
+<!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: 40px max-content max-content;grid-template-rows: 40px 40px 40px; column-gap: 20%">
+  <div></div>
+  <div style="grid-column: span 2">HH&ZeroWidthSpace;HH&ZeroWidthSpace;HH</div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/tests/generated/grid_fit_content_percent_definite_argument.rs b/tests/generated/grid_fit_content_percent_definite_argument.rs
new file mode 100644
index 000000000..9b3b4d629
--- /dev/null
+++ b/tests/generated/grid_fit_content_percent_definite_argument.rs
@@ -0,0 +1,48 @@
+#[test]
+fn grid_fit_content_percent_definite_argument() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style { ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(percent(0.5f32))],
+                size: taffy::geometry::Size { width: taffy::style::Dimension::Points(60f32), height: auto() },
+                ..Default::default()
+            },
+            &[node0],
+        )
+        .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, 60f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 60f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, 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, 30f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 30f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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);
+}
diff --git a/tests/generated/grid_fit_content_percent_definite_max_content.rs b/tests/generated/grid_fit_content_percent_definite_max_content.rs
new file mode 100644
index 000000000..1a429513a
--- /dev/null
+++ b/tests/generated/grid_fit_content_percent_definite_max_content.rs
@@ -0,0 +1,48 @@
+#[test]
+fn grid_fit_content_percent_definite_max_content() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style { ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(percent(0.5f32))],
+                size: taffy::geometry::Size { width: taffy::style::Dimension::Points(60f32), height: auto() },
+                ..Default::default()
+            },
+            &[node0],
+        )
+        .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, 60f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 60f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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);
+}
diff --git a/tests/generated/grid_fit_content_percent_definite_min_content.rs b/tests/generated/grid_fit_content_percent_definite_min_content.rs
new file mode 100644
index 000000000..308f9c1df
--- /dev/null
+++ b/tests/generated/grid_fit_content_percent_definite_min_content.rs
@@ -0,0 +1,48 @@
+#[test]
+fn grid_fit_content_percent_definite_min_content() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style { ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(percent(0.5f32))],
+                size: taffy::geometry::Size { width: taffy::style::Dimension::Points(60f32), height: auto() },
+                ..Default::default()
+            },
+            &[node0],
+        )
+        .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, 60f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 60f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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);
+}
diff --git a/tests/generated/grid_fit_content_percent_indefinite_argument.rs b/tests/generated/grid_fit_content_percent_indefinite_argument.rs
new file mode 100644
index 000000000..3f27a228f
--- /dev/null
+++ b/tests/generated/grid_fit_content_percent_indefinite_argument.rs
@@ -0,0 +1,47 @@
+#[test]
+fn grid_fit_content_percent_indefinite_argument() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style { ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH\u{200b}HH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(percent(0.5f32))],
+                ..Default::default()
+            },
+            &[node0],
+        )
+        .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, 60f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 60f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, 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, 30f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 30f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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);
+}
diff --git a/tests/generated/grid_fit_content_percent_indefinite_max_content.rs b/tests/generated/grid_fit_content_percent_indefinite_max_content.rs
new file mode 100644
index 000000000..b8067521f
--- /dev/null
+++ b/tests/generated/grid_fit_content_percent_indefinite_max_content.rs
@@ -0,0 +1,47 @@
+#[test]
+fn grid_fit_content_percent_indefinite_max_content() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style { ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(percent(0.5f32))],
+                ..Default::default()
+            },
+            &[node0],
+        )
+        .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, 20f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 20f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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);
+}
diff --git a/tests/generated/grid_fit_content_percent_indefinite_min_content.rs b/tests/generated/grid_fit_content_percent_indefinite_min_content.rs
new file mode 100644
index 000000000..ec566536f
--- /dev/null
+++ b/tests/generated/grid_fit_content_percent_indefinite_min_content.rs
@@ -0,0 +1,47 @@
+#[test]
+fn grid_fit_content_percent_indefinite_min_content() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style { ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(percent(0.5f32))],
+                ..Default::default()
+            },
+            &[node0],
+        )
+        .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, 60f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 60f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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);
+}
diff --git a/tests/generated/grid_fit_content_points_argument.rs b/tests/generated/grid_fit_content_points_argument.rs
index d2f2a80e4..30e2fdf11 100644
--- a/tests/generated/grid_fit_content_points_argument.rs
+++ b/tests/generated/grid_fit_content_points_argument.rs
@@ -4,8 +4,7 @@ fn grid_fit_content_points_argument() {
     #[allow(unused_imports)]
     use taffy::{layout::Layout, prelude::*};
     let mut taffy = taffy::Taffy::new();
-    let node0 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node1 = taffy
+    let node0 = taffy
         .new_leaf_with_measure(
             taffy::style::Style { ..Default::default() },
             taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
@@ -20,22 +19,15 @@ fn grid_fit_content_points_argument() {
             }),
         )
         .unwrap();
-    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
     let node = taffy
         .new_with_children(
             taffy::style::Style {
                 display: taffy::style::Display::Grid,
-                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
-                grid_template_columns: vec![points(40f32), fit_content(points(30f32)), points(40f32)],
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(points(30f32))],
                 ..Default::default()
             },
-            &[node0, node1, node2, node3, node4, node5, node6, node7, node8],
+            &[node0],
         )
         .unwrap();
     taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
@@ -43,53 +35,13 @@ fn grid_fit_content_points_argument() {
     taffy::debug::print_tree(&taffy, node);
     println!();
     let Layout { size, location, .. } = taffy.layout(node).unwrap();
-    assert_eq!(size.width, 110f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 110f32, size.width);
-    assert_eq!(size.height, 120f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 120f32, size.height);
+    assert_eq!(size.width, 30f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 30f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+    assert_eq!(size.width, 30f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 30f32, size.width);
     assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
-    assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.x);
-    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.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, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
-    assert_eq!(location.x, 70f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 70f32, location.x);
-    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
-    let Layout { size, location, .. } = taffy.layout(node3).unwrap();
-    assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, 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, 30f32, "width of node {:?}. Expected {}. Actual {}", node4.data(), 30f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.height);
-    assert_eq!(location.x, 70f32, "x of node {:?}. Expected {}. Actual {}", node5.data(), 70f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.height);
-    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node6.data(), 0f32, location.x);
-    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node6.data(), 80f32, location.y);
-    let Layout { size, location, .. } = taffy.layout(node7).unwrap();
-    assert_eq!(size.width, 30f32, "width of node {:?}. Expected {}. Actual {}", node7.data(), 30f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, size.height);
-    assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, location.x);
-    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node7.data(), 80f32, location.y);
-    let Layout { size, location, .. } = taffy.layout(node8).unwrap();
-    assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, size.height);
-    assert_eq!(location.x, 70f32, "x of node {:?}. Expected {}. Actual {}", node8.data(), 70f32, location.x);
-    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node8.data(), 80f32, location.y);
 }
diff --git a/tests/generated/grid_fit_content_points_max_content.rs b/tests/generated/grid_fit_content_points_max_content.rs
index dd4980fab..20a7a61aa 100644
--- a/tests/generated/grid_fit_content_points_max_content.rs
+++ b/tests/generated/grid_fit_content_points_max_content.rs
@@ -4,8 +4,7 @@ fn grid_fit_content_points_max_content() {
     #[allow(unused_imports)]
     use taffy::{layout::Layout, prelude::*};
     let mut taffy = taffy::Taffy::new();
-    let node0 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node1 = taffy
+    let node0 = taffy
         .new_leaf_with_measure(
             taffy::style::Style { ..Default::default() },
             taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
@@ -20,22 +19,15 @@ fn grid_fit_content_points_max_content() {
             }),
         )
         .unwrap();
-    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
     let node = taffy
         .new_with_children(
             taffy::style::Style {
                 display: taffy::style::Display::Grid,
-                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
-                grid_template_columns: vec![points(40f32), fit_content(points(30f32)), points(40f32)],
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(points(30f32))],
                 ..Default::default()
             },
-            &[node0, node1, node2, node3, node4, node5, node6, node7, node8],
+            &[node0],
         )
         .unwrap();
     taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
@@ -43,53 +35,13 @@ fn grid_fit_content_points_max_content() {
     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, 120f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 120f32, size.height);
+    assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 20f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+    assert_eq!(size.width, 20f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 20f32, size.width);
     assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
-    assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.x);
-    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.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, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
-    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 60f32, location.x);
-    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
-    let Layout { size, location, .. } = taffy.layout(node3).unwrap();
-    assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.height);
-    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node5.data(), 60f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.height);
-    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node6.data(), 0f32, location.x);
-    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node6.data(), 80f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, size.height);
-    assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, location.x);
-    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node7.data(), 80f32, location.y);
-    let Layout { size, location, .. } = taffy.layout(node8).unwrap();
-    assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, size.height);
-    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node8.data(), 60f32, location.x);
-    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node8.data(), 80f32, location.y);
 }
diff --git a/tests/generated/grid_fit_content_points_min_content.rs b/tests/generated/grid_fit_content_points_min_content.rs
index 437b8ba54..efdc1a92f 100644
--- a/tests/generated/grid_fit_content_points_min_content.rs
+++ b/tests/generated/grid_fit_content_points_min_content.rs
@@ -4,8 +4,7 @@ fn grid_fit_content_points_min_content() {
     #[allow(unused_imports)]
     use taffy::{layout::Layout, prelude::*};
     let mut taffy = taffy::Taffy::new();
-    let node0 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node1 = taffy
+    let node0 = taffy
         .new_leaf_with_measure(
             taffy::style::Style { ..Default::default() },
             taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
@@ -20,22 +19,15 @@ fn grid_fit_content_points_min_content() {
             }),
         )
         .unwrap();
-    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
-    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
     let node = taffy
         .new_with_children(
             taffy::style::Style {
                 display: taffy::style::Display::Grid,
-                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
-                grid_template_columns: vec![points(40f32), fit_content(points(30f32)), points(40f32)],
+                grid_template_rows: vec![points(40f32)],
+                grid_template_columns: vec![fit_content(points(30f32))],
                 ..Default::default()
             },
-            &[node0, node1, node2, node3, node4, node5, node6, node7, node8],
+            &[node0],
         )
         .unwrap();
     taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
@@ -43,8 +35,8 @@ fn grid_fit_content_points_min_content() {
     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!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 40f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 40f32, 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();
@@ -52,44 +44,4 @@ fn grid_fit_content_points_min_content() {
     assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
-    assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.x);
-    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.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, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
-    assert_eq!(location.x, 80f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 80f32, location.x);
-    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
-    let Layout { size, location, .. } = taffy.layout(node3).unwrap();
-    assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.height);
-    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node6.data(), 0f32, location.x);
-    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node6.data(), 80f32, location.y);
-    let Layout { size, location, .. } = taffy.layout(node7).unwrap();
-    assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, size.height);
-    assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, location.x);
-    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node7.data(), 80f32, location.y);
-    let Layout { size, location, .. } = taffy.layout(node8).unwrap();
-    assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, size.width);
-    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, 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_max_content_single_item_span_2.rs b/tests/generated/grid_max_content_single_item_span_2.rs
new file mode 100644
index 000000000..45457a636
--- /dev/null
+++ b/tests/generated/grid_max_content_single_item_span_2.rs
@@ -0,0 +1,101 @@
+#[test]
+fn grid_max_content_single_item_span_2() {
+    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 { ..Default::default() }).unwrap();
+    let node1 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                grid_column: taffy::geometry::Line {
+                    start: taffy::style::GridPlacement::Span(2u16),
+                    end: taffy::style::GridPlacement::Auto,
+                },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
+                grid_template_columns: vec![points(40f32), max_content(), max_content()],
+                ..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, 80f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 80f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+    assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.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, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.height);
+    assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, size.height);
+    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node4.data(), 60f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node5.data(), 0f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node5.data(), 80f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.height);
+    assert_eq!(location.x, 40f32, "x of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node6.data(), 80f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, size.height);
+    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node7.data(), 60f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node7.data(), 80f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node8).unwrap();
+    assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, size.width);
+    assert_eq!(size.height, 0f32, "height of node {:?}. Expected {}. Actual {}", node8.data(), 0f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node8.data(), 0f32, location.x);
+    assert_eq!(location.y, 120f32, "y of node {:?}. Expected {}. Actual {}", node8.data(), 120f32, location.y);
+}
diff --git a/tests/generated/grid_max_content_single_item_span_2_gap_fixed.rs b/tests/generated/grid_max_content_single_item_span_2_gap_fixed.rs
new file mode 100644
index 000000000..e4d089c26
--- /dev/null
+++ b/tests/generated/grid_max_content_single_item_span_2_gap_fixed.rs
@@ -0,0 +1,102 @@
+#[test]
+fn grid_max_content_single_item_span_2_gap_fixed() {
+    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 { ..Default::default() }).unwrap();
+    let node1 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                grid_column: taffy::geometry::Line {
+                    start: taffy::style::GridPlacement::Span(2u16),
+                    end: taffy::style::GridPlacement::Auto,
+                },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH\u{200b}HH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                gap: taffy::geometry::Size { width: taffy::style::LengthPercentage::Points(20f32), height: zero() },
+                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
+                grid_template_columns: vec![points(40f32), max_content(), max_content()],
+                ..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, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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, 60f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 60f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 60f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.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, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.height);
+    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 60f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, size.height);
+    assert_eq!(location.x, 100f32, "x of node {:?}. Expected {}. Actual {}", node4.data(), 100f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node5.data(), 0f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node5.data(), 80f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.height);
+    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node6.data(), 60f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node6.data(), 80f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, size.height);
+    assert_eq!(location.x, 100f32, "x of node {:?}. Expected {}. Actual {}", node7.data(), 100f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node7.data(), 80f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node8).unwrap();
+    assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, size.width);
+    assert_eq!(size.height, 0f32, "height of node {:?}. Expected {}. Actual {}", node8.data(), 0f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node8.data(), 0f32, location.x);
+    assert_eq!(location.y, 120f32, "y of node {:?}. Expected {}. Actual {}", node8.data(), 120f32, location.y);
+}
diff --git a/tests/generated/grid_max_content_single_item_span_2_gap_percent_definite.rs b/tests/generated/grid_max_content_single_item_span_2_gap_percent_definite.rs
new file mode 100644
index 000000000..a57842cda
--- /dev/null
+++ b/tests/generated/grid_max_content_single_item_span_2_gap_percent_definite.rs
@@ -0,0 +1,103 @@
+#[test]
+fn grid_max_content_single_item_span_2_gap_percent_definite() {
+    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 { ..Default::default() }).unwrap();
+    let node1 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                grid_column: taffy::geometry::Line {
+                    start: taffy::style::GridPlacement::Span(2u16),
+                    end: taffy::style::GridPlacement::Auto,
+                },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH\u{200b}HH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                gap: taffy::geometry::Size { width: taffy::style::LengthPercentage::Percent(0.2f32), height: zero() },
+                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
+                grid_template_columns: vec![points(40f32), max_content(), max_content()],
+                size: taffy::geometry::Size { width: taffy::style::Dimension::Points(100f32), height: auto() },
+                ..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, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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, 60f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 60f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 60f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.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, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.height);
+    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 60f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, size.height);
+    assert_eq!(location.x, 100f32, "x of node {:?}. Expected {}. Actual {}", node4.data(), 100f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node5.data(), 0f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node5.data(), 80f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.height);
+    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node6.data(), 60f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node6.data(), 80f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, size.height);
+    assert_eq!(location.x, 100f32, "x of node {:?}. Expected {}. Actual {}", node7.data(), 100f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node7.data(), 80f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node8).unwrap();
+    assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, size.width);
+    assert_eq!(size.height, 0f32, "height of node {:?}. Expected {}. Actual {}", node8.data(), 0f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node8.data(), 0f32, location.x);
+    assert_eq!(location.y, 120f32, "y of node {:?}. Expected {}. Actual {}", node8.data(), 120f32, location.y);
+}
diff --git a/tests/generated/grid_max_content_single_item_span_2_gap_percent_indefinite.rs b/tests/generated/grid_max_content_single_item_span_2_gap_percent_indefinite.rs
new file mode 100644
index 000000000..0d80d01d3
--- /dev/null
+++ b/tests/generated/grid_max_content_single_item_span_2_gap_percent_indefinite.rs
@@ -0,0 +1,102 @@
+#[test]
+fn grid_max_content_single_item_span_2_gap_percent_indefinite() {
+    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 { ..Default::default() }).unwrap();
+    let node1 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                grid_column: taffy::geometry::Line {
+                    start: taffy::style::GridPlacement::Span(2u16),
+                    end: taffy::style::GridPlacement::Auto,
+                },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HH\u{200b}HH\u{200b}HH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node2 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node3 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node4 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node5 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node6 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node7 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node8 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                gap: taffy::geometry::Size { width: taffy::style::LengthPercentage::Percent(0.2f32), height: zero() },
+                grid_template_rows: vec![points(40f32), points(40f32), points(40f32)],
+                grid_template_columns: vec![points(40f32), max_content(), max_content()],
+                ..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, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 40f32, 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, 60f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 60f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 60f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.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, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.height);
+    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 60f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, size.height);
+    assert_eq!(location.x, 100f32, "x of node {:?}. Expected {}. Actual {}", node4.data(), 100f32, 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, 40f32, "width of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node5.data(), 0f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node5.data(), 80f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.height);
+    assert_eq!(location.x, 60f32, "x of node {:?}. Expected {}. Actual {}", node6.data(), 60f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node6.data(), 80f32, 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, 40f32, "height of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, size.height);
+    assert_eq!(location.x, 100f32, "x of node {:?}. Expected {}. Actual {}", node7.data(), 100f32, location.x);
+    assert_eq!(location.y, 80f32, "y of node {:?}. Expected {}. Actual {}", node7.data(), 80f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node8).unwrap();
+    assert_eq!(size.width, 40f32, "width of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, size.width);
+    assert_eq!(size.height, 0f32, "height of node {:?}. Expected {}. Actual {}", node8.data(), 0f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node8.data(), 0f32, location.x);
+    assert_eq!(location.y, 120f32, "y of node {:?}. Expected {}. Actual {}", node8.data(), 120f32, location.y);
+}
diff --git a/tests/generated/mod.rs b/tests/generated/mod.rs
index e1740b892..1c1f11387 100644
--- a/tests/generated/mod.rs
+++ b/tests/generated/mod.rs
@@ -424,6 +424,18 @@ mod grid_basic_with_overflow;
 #[cfg(feature = "grid")]
 mod grid_basic_with_padding;
 #[cfg(feature = "grid")]
+mod grid_fit_content_percent_definite_argument;
+#[cfg(feature = "grid")]
+mod grid_fit_content_percent_definite_max_content;
+#[cfg(feature = "grid")]
+mod grid_fit_content_percent_definite_min_content;
+#[cfg(feature = "grid")]
+mod grid_fit_content_percent_indefinite_argument;
+#[cfg(feature = "grid")]
+mod grid_fit_content_percent_indefinite_max_content;
+#[cfg(feature = "grid")]
+mod grid_fit_content_percent_indefinite_min_content;
+#[cfg(feature = "grid")]
 mod grid_fit_content_points_argument;
 #[cfg(feature = "grid")]
 mod grid_fit_content_points_max_content;
@@ -506,6 +518,14 @@ mod grid_max_content_single_item_margin_fixed;
 #[cfg(feature = "grid")]
 mod grid_max_content_single_item_margin_percent;
 #[cfg(feature = "grid")]
+mod grid_max_content_single_item_span_2;
+#[cfg(feature = "grid")]
+mod grid_max_content_single_item_span_2_gap_fixed;
+#[cfg(feature = "grid")]
+mod grid_max_content_single_item_span_2_gap_percent_definite;
+#[cfg(feature = "grid")]
+mod grid_max_content_single_item_span_2_gap_percent_indefinite;
+#[cfg(feature = "grid")]
 mod grid_min_content_flex_column;
 #[cfg(feature = "grid")]
 mod grid_min_content_flex_row;