tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 788HTML 740Markdown 12TOML 62536 Sutichaykuna

Support `Overflow::Hidden` (#424)

* Impl Default for Point. Use derive for Rect and Size Default impls

* Add overflow style property

* Add scrollbar width property

* Add/fix support for overflow property to gentest script

* Enable do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent test

* Add tests for automatic minimum size of flex items with different overflow values

* Implement setting automatic minimum size of flex items to 0 for nodes with non-visible overflow

* Flexbox: only compute/store main axis resolved minimum size

* Derive Serialize/Deserialize for Point<T> when serde feature is enabled

* Add tests for automatic minimum size of grid items with different overflow values

* Add get and set methods to Point

* Implement resolving automatic minimum size to zero for grid items with non-visible overflow

* Optimise style resolution when sizing grid items

* Ensure that scrollbars take up space when generating tests

* Add support for scrollbar_width property to gentest script

* Add tests for overflow:hidden

These tests were generated by temporarily setting overflow:hidden on
every node across the entire generated test suite and then manually
creating copies of the tests with overflow:hidden for those testse
that failed.

* Use 0 when distributing intrinsic minimums of scroll containers to auto tracks, even when sizing under a min- or max-content constraint

* Apply fit-content limit to min-content contributions when item is a scroll container

* Always use indefinite main axis available space when determining flex base size

* Remove WIP overflow:scroll and overflow:auto support

* Add extra feature flags for flexbox-specific code

* Replace <head/> with </head> in test fixtures

* Add note about allow(dead_code)

b9fce82ccc823839f673144ed08f2e0e53f52b76 · ruwaq Nico Burns · (3 wata ñawpaq) · tayta 325413cd1 · kay commitpi sach'ata qhaway

Semántico sayk'uy · 91

scripts/gentest/src/main.rs

scripts/gentest/test_helper.js

src/compute/flexbox.rs

src/compute/grid/track_sizing.rs

src/compute/grid/types/grid_item.rs

src/geometry.rs

src/style/mod.rs

tests/caching.rs

tests/generated/do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.rs

tests/generated/grid_fit_content_percent_indefinite_max_content_hidden.rs

tests/generated/grid_fit_content_percent_indefinite_min_content_hidden.rs

tests/generated/grid_fit_content_points_min_content_hidden.rs

tests/generated/grid_overflow_inline_axis_hidden.rs

tests/generated/grid_overflow_inline_axis_visible.rs

tests/generated/grid_percent_items_nested_moderate.rs

tests/generated/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.rs

tests/generated/grid_span_2_max_content_auto_indefinite_hidden.rs

tests/generated/grid_span_2_max_content_fit_content_10px_indefinite_hidden.rs

tests/generated/grid_span_2_max_content_fit_content_80px_indefinite_hidden.rs

tests/generated/grid_span_2_min_content_auto_indefinite_hidden.rs

tests/generated/grid_span_2_min_content_fit_content_10px_indefinite_hidden.rs

tests/generated/grid_span_2_min_content_fit_content_30px_indefinite_hidden.rs

tests/generated/grid_span_2_min_content_fit_content_80px_indefinite_hidden.rs

tests/generated/grid_span_6_all_non_flex_indefinite_hidden.rs

tests/generated/measure_child_with_flex_shrink_hidden.rs

tests/generated/overflow_main_axis_shrink_hidden.rs

tests/generated/overflow_main_axis_shrink_visible.rs

tests/generated/percentage_moderate_complexity.rs

49 qillqakuna · +1994 −126

diff --git a/scripts/gentest/src/main.rs b/scripts/gentest/src/main.rs
index fee14f8ae..02bd0258b 100644
--- a/scripts/gentest/src/main.rs
+++ b/scripts/gentest/src/main.rs
@@ -51,6 +51,8 @@ async fn main() {
     info!("spawning webdriver client and collecting test descriptions");
     let client = ClientBuilder::native().capabilities(caps.clone()).connect(webdriver_url).await.unwrap();
 
+    asserts_non_zero_width_scrollbars(client.clone()).await;
+
     let mut test_descs = vec![];
     for (name, fixture_path) in fixtures {
         test_descs.push(test_root_element(client.clone(), name, fixture_path).await);
@@ -103,6 +105,27 @@ async fn main() {
     Command::new("cargo").arg("fmt").current_dir(repo_root).status().unwrap();
 }
 
+async fn asserts_non_zero_width_scrollbars(client: Client) {
+    // Load minimal test page defined in the string
+    const TEST_PAGE: &str = r#"data:text/html;charset=utf-8,<html><body><div style="overflow:scroll" /></body></html>"#;
+    client.goto(TEST_PAGE).await.unwrap();
+
+    // Determine the width of the scrollbar
+    let scrollbar_width = client
+        .execute("return document.body.firstChild.clientWidth - document.body.firstChild.offsetWidth;", vec![])
+        .await
+        .unwrap();
+    let Value::Number(scrollbar_width) = scrollbar_width else { panic!("Error retrieving scrollbar_width") };
+    let scrollbar_width = scrollbar_width.as_f64().unwrap();
+
+    if scrollbar_width == 0.0 {
+        panic!(concat!(
+            "\n\n    Error: Scrollbar width of zero detected. This test generation script must be run with scrollbars set to take up space.\n",
+            "    On macOS this can be done by setting Show Scrollbars to 'always' in the Appearance section of the System Settings app.\n\n"
+        ))
+    }
+}
+
 async fn test_root_element(client: Client, name: String, fixture_path: impl AsRef<Path>) -> (String, Value) {
     let fixture_path = fixture_path.as_ref();
 
@@ -352,13 +375,30 @@ fn generate_node(ident: &str, node: &Value) -> TokenStream {
         _ => quote!(),
     };
 
-    let overflow = match style["overflow"] {
-        Value::String(ref value) => match value.as_ref() {
-            "hidden" => quote!(overflow: taffy::style::Overflow::Hidden,),
-            "scroll" => quote!(overflow: taffy::style::Overflow::Scroll,),
-            _ => quote!(),
-        },
-        _ => quote!(),
+    fn quote_overflow(overflow: &Value) -> Option<TokenStream> {
+        match overflow {
+            Value::String(ref value) => match value.as_ref() {
+                "hidden" => Some(quote!(taffy::style::Overflow::Hidden)),
+                "scroll" => Some(quote!(taffy::style::Overflow::Scroll)),
+                "auto" => Some(quote!(taffy::style::Overflow::Auto)),
+                _ => None,
+            },
+            _ => None,
+        }
+    }
+    let overflow_x = quote_overflow(&style["overflowX"]);
+    let overflow_y = quote_overflow(&style["overflowY"]);
+    let (overflow, _scrollbar_width) = if overflow_x.is_some() || overflow_y.is_some() {
+        let overflow_x = overflow_x.unwrap_or(quote!(taffy::style::Overflow::Visible));
+        let overflow_y = overflow_y.unwrap_or(quote!(taffy::style::Overflow::Visible));
+        let overflow = quote!(overflow: taffy::geometry::Point { x: #overflow_x, y: #overflow_y },);
+        let scrollbar_width = quote_number_prop("scrollbar_width", style, |value: f32| {
+            let value = value as u8;
+            quote!(#value)
+        });
+        (overflow, scrollbar_width)
+    } else {
+        (quote!(), quote!())
     };
 
     let align_items = match style["alignItems"] {
diff --git a/scripts/gentest/test_helper.js b/scripts/gentest/test_helper.js
index b05eb7e7d..1b233a1e3 100644
--- a/scripts/gentest/test_helper.js
+++ b/scripts/gentest/test_helper.js
@@ -1,4 +1,13 @@
 
+function getScrollBarWidth() {
+  let el = document.createElement("div");
+  el.style.cssText = "overflow:scroll; visibility:hidden; position:absolute;";
+  document.body.appendChild(el);
+  let width = el.offsetWidth - el.clientWidth;
+  el.remove();
+  return width;
+}
+
 class TrackSizingParser {
   static INITIAL_CHAR_REGEX = /[a-z-A-Z0-9]/;
   static TOKEN_CHAR_REGEX = /[-\.a-z-A-Z0-9%]/;
@@ -188,7 +197,9 @@ function describeElement(e) {
       writingMode: parseEnum(e.style.writingMode),
 
       flexWrap: parseEnum(e.style.flexWrap),
-      overflow: parseEnum(e.style.overflow),
+      overflowX: parseEnum(e.style.overflowX),
+      overflowY: parseEnum(e.style.overflowY),
+      scrollbarWidth: getScrollBarWidth(),
 
       alignItems: parseEnum(e.style.alignItems),
       alignSelf: parseEnum(e.style.alignSelf),
diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index eef31a4ba..49ce7b350 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -11,7 +11,7 @@ use crate::prelude::{TaffyMaxContent, TaffyMinContent};
 use crate::resolve::{MaybeResolve, ResolveOrZero};
 use crate::style::{
     AlignContent, AlignItems, AlignSelf, AvailableSpace, Dimension, Display, FlexWrap, JustifyContent,
-    LengthPercentageAuto, Position,
+    LengthPercentageAuto, Overflow, Position,
 };
 use crate::style::{FlexDirection, Style};
 use crate::sys::Vec;
@@ -63,6 +63,8 @@ struct FlexItem {
     /// The cross-alignment of this item
     align_self: AlignSelf,
 
+    /// The overflow style of the item
+    overflow: Point<Overflow>,
     /// The flex shrink style of the item
     flex_shrink: f32,
     /// The flex grow style of the item
@@ -70,7 +72,7 @@ struct FlexItem {
 
     /// The minimum size of the item. This differs from min_size above because it also
     /// takes into account content based automatic minimum sizes
-    resolved_minimum_size: Size<f32>,
+    resolved_minimum_main_size: f32,
 
     /// The final offset of this item
     inset: Rect<Option<f32>>,
@@ -250,7 +252,7 @@ fn compute_preliminary(
         NODE_LOGGER.labelled_log("item.inner_flex_basis", item.inner_flex_basis);
         NODE_LOGGER.labelled_debug_log("item.hypothetical_outer_size", item.hypothetical_outer_size);
         NODE_LOGGER.labelled_debug_log("item.hypothetical_inner_size", item.hypothetical_inner_size);
-        NODE_LOGGER.labelled_debug_log("item.resolved_minimum_size", item.resolved_minimum_size);
+        NODE_LOGGER.labelled_debug_log("item.resolved_minimum_main_size", item.resolved_minimum_main_size);
     }
 
     // 4. Determine the main size of the flex container
@@ -488,6 +490,7 @@ fn generate_anonymous_flex_items(tree: &impl LayoutTree, node: Node, constants:
                 padding: child_style.padding.resolve_or_zero(constants.node_inner_size.width),
                 border: child_style.border.resolve_or_zero(constants.node_inner_size.width),
                 align_self: child_style.align_self.unwrap_or(constants.align_items),
+                overflow: child_style.overflow,
                 flex_grow: child_style.flex_grow,
                 flex_shrink: child_style.flex_shrink,
                 flex_basis: 0.0,
@@ -495,7 +498,7 @@ fn generate_anonymous_flex_items(tree: &impl LayoutTree, node: Node, constants:
                 violation: 0.0,
                 frozen: false,
 
-                resolved_minimum_size: Size::zero(),
+                resolved_minimum_main_size: 0.0,
                 hypothetical_inner_size: Size::zero(),
                 hypothetical_outer_size: Size::zero(),
                 target_size: Size::zero(),
@@ -593,7 +596,10 @@ fn determine_flex_base_size(
         let cross_axis_margin_sum = constants.margin.cross_axis_sum(dir);
         let child_min_cross = child.min_size.cross(dir).maybe_add(cross_axis_margin_sum);
         let child_max_cross = child.max_size.cross(dir).maybe_add(cross_axis_margin_sum);
-        let cross_axis_available_space = cross_axis_parent_size.maybe_clamp(child_min_cross, child_max_cross).into();
+        let cross_axis_available_space: AvailableSpace = available_space
+            .cross(dir)
+            .map_definite_value(|val| cross_axis_parent_size.unwrap_or(val))
+            .maybe_clamp(child_min_cross, child_max_cross);
 
         child.flex_basis = 'flex_basis: {
             // A. If the item has a definite used flex basis, that’s the flex base size.
@@ -637,7 +643,17 @@ fn determine_flex_base_size(
             //    flex item’s cross size. The flex base size is the item’s resulting main size.
 
             let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
-            let child_available_space = available_space.with_cross(dir, cross_axis_available_space);
+            let child_available_space = Size::MAX_CONTENT
+                .with_main(
+                    dir,
+                    // Map AvailableSpace::Definite to AvailableSpace::MaxContent
+                    if available_space.main(dir) == AvailableSpace::MinContent {
+                        AvailableSpace::MinContent
+                    } else {
+                        AvailableSpace::MaxContent
+                    },
+                )
+                .with_cross(dir, cross_axis_available_space);
 
             let child_known_dimensions = {
                 let mut ckd = child.size;
@@ -697,24 +713,28 @@ fn determine_flex_base_size(
         // be set to their usual values in the cross axis so that wrapping content can wrap correctly.
         //
         // See https://drafts.csswg.org/css-sizing-3/#min-percentage-contribution
-        let min_content_size = {
-            let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
-            let child_available_space = Size::MIN_CONTENT.with_cross(dir, cross_axis_available_space);
+        let style_min_main_size =
+            child.min_size.or(child.overflow.map(Overflow::maybe_into_automatic_min_size).into()).main(dir);
 
-            tree.measure_child_size(
-                child.node,
-                Size::NONE,
-                child_parent_size,
-                child_available_space,
-                SizingMode::ContentSize,
-            )
-        };
+        child.resolved_minimum_main_size = style_min_main_size.unwrap_or({
+            let min_content_size = {
+                let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
+                let child_available_space = Size::MIN_CONTENT.with_cross(dir, cross_axis_available_space);
 
-        // 4.5. Automatic Minimum Size of Flex Items
-        // https://www.w3.org/TR/css-flexbox-1/#min-size-auto
-        let clamped_min_content_size = min_content_size.maybe_min(child.size).maybe_min(child.max_size);
-        child.resolved_minimum_size =
-            child.min_size.unwrap_or(clamped_min_content_size).maybe_max(padding_border_axes_sums);
+                tree.measure_child_size(
+                    child.node,
+                    Size::NONE,
+                    child_parent_size,
+                    child_available_space,
+                    SizingMode::ContentSize,
+                )
+            };
+
+            // 4.5. Automatic Minimum Size of Flex Items
+            // https://www.w3.org/TR/css-flexbox-1/#min-size-auto
+            let clamped_min_content_size = min_content_size.maybe_min(child.size).maybe_min(child.max_size);
+            clamped_min_content_size.maybe_max(padding_border_axes_sums).main(dir)
+        });
     }
 }
 
@@ -875,12 +895,11 @@ fn determine_container_main_size(
                         let flex_basis_min = clamping_basis.filter(|_| item.flex_shrink == 0.0);
                         let flex_basis_max = clamping_basis.filter(|_| item.flex_grow == 0.0);
 
-                        let resolved_min = item.resolved_minimum_size.main(constants.dir);
                         let min_main_size = style_min
                             .maybe_max(flex_basis_min)
                             .or(flex_basis_min)
-                            .unwrap_or(resolved_min)
-                            .max(resolved_min);
+                            .unwrap_or(item.resolved_minimum_main_size)
+                            .max(item.resolved_minimum_main_size);
                         let max_main_size =
                             style_max.maybe_min(flex_basis_max).or(flex_basis_max).unwrap_or(f32::INFINITY);
 
@@ -1151,7 +1170,7 @@ fn resolve_flexible_lengths(line: &mut FlexLine, constants: &AlgoConstants, orig
         //    If the item’s target main size was made larger by this, it’s a min violation.
 
         let total_violation = unfrozen.iter_mut().fold(0.0, |acc, child| -> f32 {
-            let resolved_min_main: Option<f32> = child.resolved_minimum_size.main(constants.dir).into();
+            let resolved_min_main: Option<f32> = child.resolved_minimum_main_size.into();
             let max_main = child.max_size.main(constants.dir);
             let clamped = child.target_size.main(constants.dir).maybe_clamp(resolved_min_main, max_main).max(0.0);
             child.violation = clamped - child.target_size.main(constants.dir);
diff --git a/src/compute/grid/track_sizing.rs b/src/compute/grid/track_sizing.rs
index cfd415487..4d1137cb3 100644
--- a/src/compute/grid/track_sizing.rs
+++ b/src/compute/grid/track_sizing.rs
@@ -562,13 +562,23 @@ fn resolve_intrinsic_track_sizes(
                     }
                     MinTrackSizingFunction::Auto => {
                         let space = match axis_available_grid_space {
-                            AvailableSpace::MinContent | AvailableSpace::MaxContent => {
+                            // QUIRK: The spec says that:
+                            //
+                            //   If the grid container is being sized under a min- or max-content constraint, use the items’ limited
+                            //   min-content contributions in place of their minimum contributions here.
+                            //
+                            // However, in practice browsers only seem to apply this rule if the item is not a scroll container
+                            // (note that overflow:hidden counts as a scroll container), giving the automatic minimum size of scroll
+                            // containers (zero) precedence over the min-content contributions.
+                            AvailableSpace::MinContent | AvailableSpace::MaxContent
+                                if !item.overflow.get(axis).is_scroll_container() =>
+                            {
                                 let axis_minimum_size = item_sizer.minimum_contribution(item, axis_tracks);
                                 let axis_min_content_size = item_sizer.min_content_contribution(item);
                                 let limit = track.max_track_sizing_function.definite_limit(axis_inner_node_size);
                                 axis_min_content_size.maybe_min(limit).max(axis_minimum_size)
                             }
-                            AvailableSpace::Definite(_) => item_sizer.minimum_contribution(item, axis_tracks),
+                            _ => item_sizer.minimum_contribution(item, axis_tracks),
                         };
                         f32_max(track.base_size, space)
                     }
@@ -582,12 +592,19 @@ fn resolve_intrinsic_track_sizes(
 
                 // Handle growth limits
                 if let MaxTrackSizingFunction::FitContent(_) = track.max_track_sizing_function {
+                    // If item is not a scroll container, then increase the growth limit to at least the
+                    // size of the min-content contribution
+                    if !item.overflow.get(axis).is_scroll_container() {
+                        let min_content_contribution = item_sizer.min_content_contribution(item);
+                        track.growth_limit_planned_increase =
+                            f32_max(track.growth_limit_planned_increase, min_content_contribution);
+                    }
+
+                    // Always increase the growth limit to at least the size of the *fit-content limited*
+                    // max-cotent contribution
                     let fit_content_limit = track.fit_content_limit(axis_inner_node_size);
-                    let min_content_contribution = item_sizer.min_content_contribution(item);
                     let max_content_contribution =
                         f32_min(item_sizer.max_content_contribution(item), fit_content_limit);
-                    track.growth_limit_planned_increase =
-                        f32_max(track.growth_limit_planned_increase, min_content_contribution);
                     track.growth_limit_planned_increase =
                         f32_max(track.growth_limit_planned_increase, max_content_contribution);
                 } else if track.max_track_sizing_function.is_max_content_alike()
@@ -629,28 +646,49 @@ fn resolve_intrinsic_track_sizes(
             move |track: &GridTrack| track.min_track_sizing_function.definite_value(axis_inner_node_size).is_none();
         for item in batch.iter_mut().filter(|item| item.crosses_intrinsic_track(axis)) {
             // ...by distributing extra space as needed to accommodate these items’ minimum contributions.
-            // If the grid container is being sized under a min- or max-content constraint, use the items’ limited min-content contributions
-            // in place of their minimum contributions here.
+            //
+            // QUIRK: The spec says that:
+            //
+            //   If the grid container is being sized under a min- or max-content constraint, use the items’ limited min-content contributions
+            //   in place of their minimum contributions here.
+            //
+            // However, in practice browsers only seem to apply this rule if the item is not a scroll container (note that overflow:hidden counts as
+            // a scroll container), giving the automatic minimum size of scroll containers (zero) precedence over the min-content contributions.
             let space = match axis_available_grid_space {
-                AvailableSpace::MinContent | AvailableSpace::MaxContent => {
+                AvailableSpace::MinContent | AvailableSpace::MaxContent
+                    if !item.overflow.get(axis).is_scroll_container() =>
+                {
                     let axis_minimum_size = item_sizer.minimum_contribution(item, axis_tracks);
                     let axis_min_content_size = item_sizer.min_content_contribution(item);
                     let limit = item.spanned_track_limit(axis, axis_tracks, axis_inner_node_size);
                     axis_min_content_size.maybe_min(limit).max(axis_minimum_size)
                 }
-                AvailableSpace::Definite(_) => item_sizer.minimum_contribution(item, axis_tracks),
+                _ => item_sizer.minimum_contribution(item, axis_tracks),
             };
             let tracks = &mut axis_tracks[item.track_range_excluding_lines(axis)];
             if space > 0.0 {
-                distribute_item_space_to_base_size(
-                    is_flex,
-                    use_flex_factor_for_distribution,
-                    space,
-                    tracks,
-                    has_intrinsic_min_track_sizing_function,
-                    |_| f32::INFINITY,
-                    IntrinsicContributionType::Minimum,
-                );
+                if item.overflow.get(axis).is_scroll_container() {
+                    let fit_content_limit = move |track: &GridTrack| track.fit_content_limit(axis_inner_node_size);
+                    distribute_item_space_to_base_size(
+                        is_flex,
+                        use_flex_factor_for_distribution,
+                        space,
+                        tracks,
+                        has_intrinsic_min_track_sizing_function,
+                        fit_content_limit,
+                        IntrinsicContributionType::Minimum,
+                    );
+                } else {
+                    distribute_item_space_to_base_size(
+                        is_flex,
+                        use_flex_factor_for_distribution,
+                        space,
+                        tracks,
+                        has_intrinsic_min_track_sizing_function,
+                        |_| f32::INFINITY,
+                        IntrinsicContributionType::Minimum,
+                    );
+                }
             }
         }
         flush_planned_base_size_increases(axis_tracks);
@@ -666,15 +704,28 @@ fn resolve_intrinsic_track_sizes(
             let space = item_sizer.min_content_contribution(item);
             let tracks = &mut axis_tracks[item.track_range_excluding_lines(axis)];
             if space > 0.0 {
-                distribute_item_space_to_base_size(
-                    is_flex,
-                    use_flex_factor_for_distribution,
-                    space,
-                    tracks,
-                    has_min_or_max_content_min_track_sizing_function,
-                    |_| f32::INFINITY,
-                    IntrinsicContributionType::Minimum,
-                );
+                if item.overflow.get(axis).is_scroll_container() {
+                    let fit_content_limit = move |track: &GridTrack| track.fit_content_limit(axis_inner_node_size);
+                    distribute_item_space_to_base_size(
+                        is_flex,
+                        use_flex_factor_for_distribution,
+                        space,
+                        tracks,
+                        has_min_or_max_content_min_track_sizing_function,
+                        fit_content_limit,
+                        IntrinsicContributionType::Minimum,
+                    );
+                } else {
+                    distribute_item_space_to_base_size(
+                        is_flex,
+                        use_flex_factor_for_distribution,
+                        space,
+                        tracks,
+                        has_min_or_max_content_min_track_sizing_function,
+                        |_| f32::INFINITY,
+                        IntrinsicContributionType::Minimum,
+                    );
+                }
             }
         }
         flush_planned_base_size_increases(axis_tracks);
diff --git a/src/compute/grid/types/grid_item.rs b/src/compute/grid/types/grid_item.rs
index cd9fb8234..f6be292c7 100644
--- a/src/compute/grid/types/grid_item.rs
+++ b/src/compute/grid/types/grid_item.rs
@@ -2,14 +2,15 @@
 use super::GridTrack;
 use crate::axis::AbstractAxis;
 use crate::compute::grid::OriginZeroLine;
-use crate::geometry::{Line, Rect, Size};
+use crate::geometry::{Line, Point, Rect, Size};
 use crate::layout::SizingMode;
 use crate::math::MaybeMath;
 use crate::node::Node;
 use crate::prelude::LayoutTree;
 use crate::resolve::{MaybeResolve, ResolveOrZero};
 use crate::style::{
-    AlignItems, AlignSelf, AvailableSpace, LengthPercentageAuto, MaxTrackSizingFunction, MinTrackSizingFunction, Style,
+    AlignItems, AlignSelf, AvailableSpace, Dimension, LengthPercentageAuto, MaxTrackSizingFunction,
+    MinTrackSizingFunction, Overflow, Style,
 };
 use core::ops::Range;
 
@@ -32,6 +33,16 @@ pub(in super::super) struct GridItem {
     /// (in origin-zero coordinates)
     pub column: Line<OriginZeroLine>,
 
+    /// The item's overflow style
+    pub overflow: Point<Overflow>,
+    /// The item's size style
+    pub size: Size<Dimension>,
+    /// The item's min_size style
+    pub min_size: Size<Dimension>,
+    /// The item's max_size style
+    pub max_size: Size<Dimension>,
+    /// The item's aspect_ratio style
+    pub aspect_ratio: Option<f32>,
     /// The item's margin style
     pub margin: Rect<LengthPercentageAuto>,
     /// The item's align_self property, or the parent's align_items property is not set
@@ -87,6 +98,11 @@ impl GridItem {
             source_order,
             row: row_span,
             column: col_span,
+            overflow: style.overflow,
+            size: style.size,
+            min_size: style.min_size,
+            max_size: style.max_size,
+            aspect_ratio: style.aspect_ratio,
             margin: style.margin,
             align_self: style.align_self.unwrap_or(parent_align_items),
             justify_self: style.justify_self.unwrap_or(parent_justify_items),
@@ -206,17 +222,15 @@ impl GridItem {
     /// allow percentage sizes further down the tree to resolve properly in some cases
     fn known_dimensions(
         &self,
-        tree: &mut impl LayoutTree,
         inner_node_size: Size<Option<f32>>,
         grid_area_size: Size<Option<f32>>,
     ) -> Size<Option<f32>> {
         let margins = self.margins_axis_sums_with_baseline_shims(inner_node_size.width);
 
-        let style = tree.style(self.node);
-        let aspect_ratio = style.aspect_ratio;
-        let inherent_size = style.size.maybe_resolve(grid_area_size).maybe_apply_aspect_ratio(aspect_ratio);
-        let min_size = style.min_size.maybe_resolve(grid_area_size).maybe_apply_aspect_ratio(aspect_ratio);
-        let max_size = style.max_size.maybe_resolve(grid_area_size).maybe_apply_aspect_ratio(aspect_ratio);
+        let aspect_ratio = self.aspect_ratio;
+        let inherent_size = self.size.maybe_resolve(grid_area_size).maybe_apply_aspect_ratio(aspect_ratio);
+        let min_size = self.min_size.maybe_resolve(grid_area_size).maybe_apply_aspect_ratio(aspect_ratio);
+        let max_size = self.max_size.maybe_resolve(grid_area_size).maybe_apply_aspect_ratio(aspect_ratio);
 
         let grid_area_minus_item_margins_size = grid_area_size.maybe_sub(margins);
 
@@ -227,8 +241,8 @@ impl GridItem {
             //  - Alignment style is "stretch"
             //  - The node is not absolutely positioned
             //  - The node does not have auto margins in this axis.
-            if style.margin.left != LengthPercentageAuto::Auto
-                && style.margin.right != LengthPercentageAuto::Auto
+            if self.margin.left != LengthPercentageAuto::Auto
+                && self.margin.right != LengthPercentageAuto::Auto
                 && self.justify_self == AlignSelf::Stretch
             {
                 return grid_area_minus_item_margins_size.width;
@@ -245,8 +259,8 @@ impl GridItem {
             //  - Alignment style is "stretch"
             //  - The node is not absolutely positioned
             //  - The node does not have auto margins in this axis.
-            if style.margin.top != LengthPercentageAuto::Auto
-                && style.margin.bottom != LengthPercentageAuto::Auto
+            if self.margin.top != LengthPercentageAuto::Auto
+                && self.margin.bottom != LengthPercentageAuto::Auto
                 && self.align_self == AlignSelf::Stretch
             {
                 return grid_area_minus_item_margins_size.height;
@@ -326,7 +340,7 @@ impl GridItem {
         available_space: Size<Option<f32>>,
         inner_node_size: Size<Option<f32>>,
     ) -> f32 {
-        let known_dimensions = self.known_dimensions(tree, inner_node_size, available_space);
+        let known_dimensions = self.known_dimensions(inner_node_size, available_space);
         tree.measure_child_size(
             self.node,
             known_dimensions,
@@ -364,7 +378,7 @@ impl GridItem {
         available_space: Size<Option<f32>>,
         inner_node_size: Size<Option<f32>>,
     ) -> f32 {
-        let known_dimensions = self.known_dimensions(tree, inner_node_size, available_space);
+        let known_dimensions = self.known_dimensions(inner_node_size, available_space);
         tree.measure_child_size(
             self.node,
             known_dimensions,
@@ -409,15 +423,15 @@ impl GridItem {
         known_dimensions: Size<Option<f32>>,
         inner_node_size: Size<Option<f32>>,
     ) -> f32 {
-        let style = tree.style(self.node);
-        let size = style
+        let size = self
             .size
             .maybe_resolve(inner_node_size)
-            .maybe_apply_aspect_ratio(style.aspect_ratio)
+            .maybe_apply_aspect_ratio(self.aspect_ratio)
             .get(axis)
             .or_else(|| {
-                style.min_size.maybe_resolve(inner_node_size).maybe_apply_aspect_ratio(style.aspect_ratio).get(axis)
+                self.min_size.maybe_resolve(inner_node_size).maybe_apply_aspect_ratio(self.aspect_ratio).get(axis)
             })
+            .or_else(|| self.overflow.get(axis).maybe_into_automatic_min_size())
             .unwrap_or_else(|| {
                 // Automatic minimum size. See https://www.w3.org/TR/css-grid-1/#min-size-auto
 
diff --git a/src/geometry.rs b/src/geometry.rs
index 65dce8e3e..e0ebad338 100644
--- a/src/geometry.rs
+++ b/src/geometry.rs
@@ -11,7 +11,7 @@ use crate::style::FlexDirection;
 use crate::axis::AbstractAxis;
 
 /// An axis-aligned UI rectangle
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 pub struct Rect<T> {
     /// This can represent either the x-coordinate of the starting edge,
@@ -34,17 +34,6 @@ pub struct Rect<T> {
     pub bottom: T,
 }
 
-impl<T: Default> Default for Rect<T> {
-    fn default() -> Self {
-        Rect {
-            left: Default::default(),
-            right: Default::default(),
-            top: Default::default(),
-            bottom: Default::default(),
-        }
-    }
-}
-
 impl<U, T: Add<U>> Add<Rect<U>> for Rect<T> {
     type Output = Rect<T::Output>;
 
@@ -248,7 +237,7 @@ impl<T: Add + Copy> Line<T> {
 }
 
 /// The width and height of a [`Rect`]
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 pub struct Size<T> {
     /// The x extent of the rectangle
@@ -257,12 +246,6 @@ pub struct Size<T> {
     pub height: T,
 }
 
-impl<T: Default> Default for Size<T> {
-    fn default() -> Self {
-        Size { width: Default::default(), height: Default::default() }
-    }
-}
-
 // Generic Add impl for Size<T> + Size<U> where T + U has an Add impl
 impl<U, T: Add<U>> Add<Size<U>> for Size<T> {
     type Output = Size<<T as Add<U>>::Output>;
@@ -272,6 +255,9 @@ impl<U, T: Add<U>> Add<Size<U>> for Size<T> {
     }
 }
 
+// Note: we allow dead_code here as we want to provide a complete API of helpers that is symetrical in all axes,
+// but sometimes we only currently have a use for the helper in a single axis
+#[allow(dead_code)]
 impl<T> Size<T> {
     /// Applies the function `f` to both the width and height
     ///
@@ -335,7 +321,6 @@ impl<T> Size<T> {
     /// Creates a new value of type Self with the main axis set to value provided
     ///
     /// Whether this is the width or height depends on the `direction` provided
-    #[allow(dead_code)]
     #[cfg(feature = "flexbox")]
     pub(crate) fn with_main(self, direction: FlexDirection, value: T) -> Self {
         let mut new = self;
@@ -361,6 +346,34 @@ impl<T> Size<T> {
         new
     }
 
+    /// Creates a new value of type Self with the main axis modified by the callback provided
+    ///
+    /// Whether this is the width or height depends on the `direction` provided
+    #[cfg(feature = "flexbox")]
+    pub(crate) fn map_main(self, direction: FlexDirection, mapper: impl FnOnce(T) -> T) -> Self {
+        let mut new = self;
+        if direction.is_row() {
+            new.width = mapper(new.width);
+        } else {
+            new.height = mapper(new.height);
+        }
+        new
+    }
+
+    /// Creates a new value of type Self with the cross axis modified by the callback provided
+    ///
+    /// Whether this is the width or height depends on the `direction` provided
+    #[cfg(feature = "flexbox")]
+    pub(crate) fn map_cross(self, direction: FlexDirection, mapper: impl FnOnce(T) -> T) -> Self {
+        let mut new = self;
+        if direction.is_row() {
+            new.height = mapper(new.height);
+        } else {
+            new.width = mapper(new.width);
+        }
+        new
+    }
+
     /// Gets the extent of the main layout axis
     ///
     /// Whether this is the width or height depends on the `direction` provided
@@ -478,7 +491,8 @@ impl Size<Dimension> {
 /// A 2-dimensional coordinate.
 ///
 /// When used in association with a [`Rect`], represents the bottom-left corner.
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+#[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
 pub struct Point<T> {
     /// The x-coordinate
     pub x: T,
@@ -496,6 +510,44 @@ impl Point<Option<f32>> {
     pub const NONE: Self = Self { x: None, y: None };
 }
 
+impl<T> Point<T> {
+    /// Applies the function `f` to both the x and y
+    ///
+    /// This is used to transform a `Point<T>` into a `Point<R>`.
+    pub fn map<R, F>(self, f: F) -> Point<R>
+    where
+        F: Fn(T) -> R,
+    {
+        Point { x: f(self.x), y: f(self.y) }
+    }
+
+    /// Gets the extent of the specified layout axis
+    /// Whether this is the width or height depends on the `GridAxis` provided
+    #[cfg(feature = "grid")]
+    pub fn get(self, axis: AbstractAxis) -> T {
+        match axis {
+            AbstractAxis::Inline => self.x,
+            AbstractAxis::Block => self.y,
+        }
+    }
+
+    /// Sets the extent of the specified layout axis
+    /// Whether this is the width or height depends on the `GridAxis` provided
+    #[cfg(feature = "grid")]
+    pub fn set(&mut self, axis: AbstractAxis, value: T) {
+        match axis {
+            AbstractAxis::Inline => self.x = value,
+            AbstractAxis::Block => self.y = value,
+        }
+    }
+}
+
+impl<T> From<Point<T>> for Size<T> {
+    fn from(value: Point<T>) -> Self {
+        Size { width: value.x, height: value.y }
+    }
+}
+
 /// Generic struct which holds a "min" value and a "max" value
 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
 #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
diff --git a/src/style/mod.rs b/src/style/mod.rs
index a784bd6e8..d7e169053 100644
--- a/src/style/mod.rs
+++ b/src/style/mod.rs
@@ -20,7 +20,7 @@ pub use self::grid::{
     GridAutoFlow, GridPlacement, GridTrackRepetition, MaxTrackSizingFunction, MinTrackSizingFunction,
     NonRepeatedTrackSizingFunction, TrackSizingFunction,
 };
-use crate::geometry::{Rect, Size};
+use crate::geometry::{Point, Rect, Size};
 
 #[cfg(feature = "grid")]
 use crate::geometry::Line;
@@ -94,6 +94,46 @@ impl Default for Position {
     }
 }
 
+/// How children overflowing their container should affect layout
+///
+/// In CSS the primary effect of this property is to control whether contents of a parent container that overflow that container should
+/// be displayed anyway, be clipped, or trigger the container to become a scroll container. However it also has secondary effects on layout,
+/// the main ones being:
+///
+///   - The automatic minimum size Flexbox/CSS Grid items with non-`Visible` overflow is `0` rather than being content based
+///
+/// In Taffy, we only implement the layout related secondary effects as we are not concerned with drawing/painting.
+///
+/// <https://developer.mozilla.org/en-US/docs/Web/CSS/overflow>
+#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
+#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
+pub enum Overflow {
+    /// The automatic minimum size of this node as a flexbox/grid item should be based on the size of it's content.
+    #[default]
+    Visible,
+    /// The automatic minimum size of this node as a flexbox/grid item should be `0`.
+    Hidden,
+}
+
+impl Overflow {
+    /// Returns true for overflow modes that contain their contents (`Overflow::Hidden`, `Overflow::Scroll`, `Overflow::Auto`)
+    /// or else false for overflow modes that allow their contains to spill (`Overflow::Visible`).
+    #[inline(always)]
+    pub(crate) fn is_scroll_container(self) -> bool {
+        self != Overflow::Visible
+    }
+
+    /// Returns `Some(0.0)` if the overflow mode would cause the automatic minimum size of a Flexbox or CSS Grid item
+    /// to be `0`. Else returns None.
+    #[inline(always)]
+    pub(crate) fn maybe_into_automatic_min_size(self) -> Option<f32> {
+        match self.is_scroll_container() {
+            true => Some(0.0),
+            false => None,
+        }
+    }
+}
+
 /// The flexbox layout information for a single [`Node`](crate::node::Node).
 ///
 /// The most important idea in flexbox is the notion of a "main" and "cross" axis, which are always perpendicular to each other.
@@ -115,6 +155,10 @@ pub struct Style {
     /// What layout strategy should be used?
     pub display: Display,
 
+    // Overflow properties
+    /// How children overflowing their container should affect layout
+    pub overflow: Point<Overflow>,
+
     // Position properties
     /// What should the `position` value of this struct use as a base offset?
     pub position: Position,
@@ -225,6 +269,7 @@ impl Style {
     /// The [`Default`] layout, in a form that can be used in const functions
     pub const DEFAULT: Style = Style {
         display: Display::DEFAULT,
+        overflow: Point { x: Overflow::Visible, y: Overflow::Visible },
         position: Position::Relative,
         inset: Rect::auto(),
         margin: Rect::zero(),
@@ -296,6 +341,7 @@ mod tests {
 
         let old_defaults = Style {
             display: Default::default(),
+            overflow: Default::default(),
             position: Default::default(),
             #[cfg(feature = "flexbox")]
             flex_direction: Default::default(),
@@ -375,6 +421,7 @@ mod tests {
         // Display and Position
         assert_type_size::<Display>(1);
         assert_type_size::<Position>(1);
+        assert_type_size::<Overflow>(1);
 
         // Dimensions and aggregations of Dimensions
         assert_type_size::<f32>(4);
diff --git a/test_fixtures/xdo_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.html b/test_fixtures/do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.html
similarity index 100%
rename from test_fixtures/xdo_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.html
rename to test_fixtures/do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.html
diff --git a/test_fixtures/grid_fit_content_percent_indefinite_max_content_hidden.html b/test_fixtures/grid_fit_content_percent_indefinite_max_content_hidden.html
new file mode 100644
index 000000000..95d61db9b
--- /dev/null
+++ b/test_fixtures/grid_fit_content_percent_indefinite_max_content_hidden.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 style="overflow: hidden;">HH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_fit_content_percent_indefinite_min_content_hidden.html b/test_fixtures/grid_fit_content_percent_indefinite_min_content_hidden.html
new file mode 100644
index 000000000..a02c71614
--- /dev/null
+++ b/test_fixtures/grid_fit_content_percent_indefinite_min_content_hidden.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 style="overflow: hidden;">HHHH&ZeroWidthSpace;HH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_fit_content_points_min_content_hidden.html b/test_fixtures/grid_fit_content_points_min_content_hidden.html
new file mode 100644
index 000000000..84f675243
--- /dev/null
+++ b/test_fixtures/grid_fit_content_points_min_content_hidden.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(30px);grid-template-rows: 40px">
+  <div style="overflow: hidden;">HHHH&ZeroWidthSpace;HH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_overflow_inline_axis_hidden.html b/test_fixtures/grid_overflow_inline_axis_hidden.html
new file mode 100644
index 000000000..d71fb04fa
--- /dev/null
+++ b/test_fixtures/grid_overflow_inline_axis_hidden.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:50px; height: 50px;">
+  <div style="overflow: hidden;">HHHHHHHHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_overflow_inline_axis_visible.html b/test_fixtures/grid_overflow_inline_axis_visible.html
new file mode 100644
index 000000000..e62f76208
--- /dev/null
+++ b/test_fixtures/grid_overflow_inline_axis_visible.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:50px; height: 50px;">
+  <div style="overflow: visible;">HHHHHHHHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.html b/test_fixtures/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.html
new file mode 100644
index 000000000..3ca067899
--- /dev/null
+++ b/test_fixtures/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.html
@@ -0,0 +1,34 @@
+<!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-rows: 40px 40px;
+  grid-template-columns: min-content max-content fit-content(20px) auto 10px 20% minmax(2px, auto) minmax(2px, 4px) minmax(2px, min-content) minmax(2px, max-content) minmax(min-content, max-content) minmax(min-content, auto) minmax(max-content, auto);
+">
+  <div style="grid-column: 1 / span 13;overflow: hidden;">HHHHHHHHHHHHHHHH&ZeroWidthSpace;HHHHHHHHHHHHHHHH</div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></div>
+  <div></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_span_2_max_content_auto_indefinite_hidden.html b/test_fixtures/grid_span_2_max_content_auto_indefinite_hidden.html
new file mode 100644
index 000000000..e303b382f
--- /dev/null
+++ b/test_fixtures/grid_span_2_max_content_auto_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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:max-content auto;grid-template-rows: 40px">
+  <div style="grid-row: 1; grid-column: 1"></div>
+  <div style="grid-row: 1; grid-column: 2"></div>
+  <div style="grid-row: 1; grid-column: 1 / span 2; overflow: hidden;>HHHH&ZeroWidthSpace;HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_max_content_fit_content_10px_indefinite_hidden.html b/test_fixtures/grid_span_2_max_content_fit_content_10px_indefinite_hidden.html
new file mode 100644
index 000000000..2e74e60e5
--- /dev/null
+++ b/test_fixtures/grid_span_2_max_content_fit_content_10px_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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:max-content fit-content(10px);grid-template-rows: 40px">
+  <div style="grid-row: 1; grid-column: 1"></div>
+  <div style="grid-row: 1; grid-column: 2"></div>
+  <div style="grid-row: 1; grid-column: 1 / span 2; overflow: hidden">HHHH&ZeroWidthSpace;HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_max_content_fit_content_80px_indefinite_hidden.html b/test_fixtures/grid_span_2_max_content_fit_content_80px_indefinite_hidden.html
new file mode 100644
index 000000000..8db65781c
--- /dev/null
+++ b/test_fixtures/grid_span_2_max_content_fit_content_80px_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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:max-content fit-content(80px);grid-template-rows: 40px">
+  <div style="grid-row: 1; grid-column: 1"></div>
+  <div style="grid-row: 1; grid-column: 2"></div>
+  <div style="grid-row: 1; grid-column: 1 / span 2;overflow: hidden">HHHH&ZeroWidthSpace;HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_min_content_auto_indefinite_hidden.html b/test_fixtures/grid_span_2_min_content_auto_indefinite_hidden.html
new file mode 100644
index 000000000..bf33749a9
--- /dev/null
+++ b/test_fixtures/grid_span_2_min_content_auto_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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:min-content auto;grid-template-rows: 40px">
+  <div></div>
+  <div></div>
+  <div style="grid-column: 1 / span 2;overflow: hidden;">HHHH&ZeroWidthSpace;HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_min_content_fit_content_10px_indefinite_hidden.html b/test_fixtures/grid_span_2_min_content_fit_content_10px_indefinite_hidden.html
new file mode 100644
index 000000000..4971d2d64
--- /dev/null
+++ b/test_fixtures/grid_span_2_min_content_fit_content_10px_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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:min-content fit-content(10px);grid-template-rows: 40px">
+  <div style="grid-row: 1; grid-column: 1"></div>
+  <div style="grid-row: 1; grid-column: 2"></div>
+  <div style="grid-row: 1; grid-column: 1 / span 2; overflow: hidden;">HHHH&ZeroWidthSpace;HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_min_content_fit_content_30px_indefinite_hidden.html b/test_fixtures/grid_span_2_min_content_fit_content_30px_indefinite_hidden.html
new file mode 100644
index 000000000..d17b1dc1d
--- /dev/null
+++ b/test_fixtures/grid_span_2_min_content_fit_content_30px_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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:min-content fit-content(30px);grid-template-rows: 40px">
+  <div style="grid-row: 1; grid-column: 1"></div>
+  <div style="grid-row: 1; grid-column: 2"></div>
+  <div style="grid-row: 1; grid-column: 1 / span 2; overflow: hidden;">HHHH&ZeroWidthSpace;HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_2_min_content_fit_content_80px_indefinite_hidden.html b/test_fixtures/grid_span_2_min_content_fit_content_80px_indefinite_hidden.html
new file mode 100644
index 000000000..aba6ee46f
--- /dev/null
+++ b/test_fixtures/grid_span_2_min_content_fit_content_80px_indefinite_hidden.html
@@ -0,0 +1,19 @@
+<!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:min-content fit-content(80px);grid-template-rows: 40px">
+  <div style="grid-row: 1; grid-column: 1"></div>
+  <div style="grid-row: 1; grid-column: 2"></div>
+  <div style="grid-row: 1; grid-column: 1 / span 2;overflow: hidden;">HHHH&ZeroWidthSpace;HHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/grid_span_6_all_non_flex_indefinite_hidden.html b/test_fixtures/grid_span_6_all_non_flex_indefinite_hidden.html
new file mode 100644
index 000000000..495f58259
--- /dev/null
+++ b/test_fixtures/grid_span_6_all_non_flex_indefinite_hidden.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+</head>
+<body>
+
+<div id="test-root" style="display: grid; grid-template-columns:min-content max-content fit-content(20px) auto 10px 20%;grid-template-rows: 40px 40px">
+  <div style="grid-column: 1 / span 6;overflow: hidden">HHHHHHHH&ZeroWidthSpace;HHHHHHHH</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/measure_child_with_flex_shrink_hidden.html b/test_fixtures/measure_child_with_flex_shrink_hidden.html
new file mode 100644
index 000000000..07797f5c3
--- /dev/null
+++ b/test_fixtures/measure_child_with_flex_shrink_hidden.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <script src="../scripts/gentest/test_helper.js"></script>
+  <link rel="stylesheet" type="text/css" href="../scripts/gentest/test_base_style.css">
+  <title>
+    Test description
+  </title>
+</head>
+<body>
+
+<div id="test-root" style="width:100px; height: auto">
+  <div style="width: 50px;height: 50px"></div>
+  <div style="overflow: hidden;">HHHHHHHHHH&ZeroWidthSpace;HHHHHHHHHH&ZeroWidthSpace;HHHHHHHHHH&ZeroWidthSpace;HHHHHHHHHH&ZeroWidthSpace;HHHHHHHHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/overflow_main_axis_shrink_hidden.html b/test_fixtures/overflow_main_axis_shrink_hidden.html
new file mode 100644
index 000000000..68c34189b
--- /dev/null
+++ b/test_fixtures/overflow_main_axis_shrink_hidden.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="width:50px; height: 50px;">
+  <div style="flex-shrink: 1;overflow: hidden;">HHHHHHHHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/overflow_main_axis_shrink_visible.html b/test_fixtures/overflow_main_axis_shrink_visible.html
new file mode 100644
index 000000000..f47f1bb43
--- /dev/null
+++ b/test_fixtures/overflow_main_axis_shrink_visible.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="width:50px; height: 50px;">
+  <div style="flex-shrink: 1;overflow: visible;">HHHHHHHHHH</div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/test_fixtures/xflex_basis_zero_undefined_main_size_hidden.html b/test_fixtures/xflex_basis_zero_undefined_main_size_hidden.html
new file mode 100644
index 000000000..5b47628bb
--- /dev/null
+++ b/test_fixtures/xflex_basis_zero_undefined_main_size_hidden.html
@@ -0,0 +1,19 @@
+<!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="flex-direction: row;">
+  <div style="flex-direction: column;flex-basis: 0px;overflow: hidden;">
+    <div style="width: 100px; height: 50px;"></div>
+  </div>
+</div>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/tests/caching.rs b/tests/caching.rs
index 581ce43e9..a1a3c2fb6 100644
--- a/tests/caching.rs
+++ b/tests/caching.rs
@@ -30,7 +30,7 @@ mod caching {
 
         taffy.compute_layout(node, Size::MAX_CONTENT).unwrap();
 
-        assert_eq!(NUM_MEASURES.load(Ordering::SeqCst), 8);
+        assert_eq!(NUM_MEASURES.load(Ordering::SeqCst), 3);
     }
 
     #[test]
@@ -62,6 +62,6 @@ mod caching {
         }
 
         taffy.compute_layout(node, Size::MAX_CONTENT).unwrap();
-        assert_eq!(NUM_MEASURES.load(Ordering::SeqCst), 8);
+        assert_eq!(NUM_MEASURES.load(Ordering::SeqCst), 3);
     }
 }
diff --git a/tests/generated/do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.rs b/tests/generated/do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.rs
new file mode 100644
index 000000000..c747ba6ed
--- /dev/null
+++ b/tests/generated/do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent.rs
@@ -0,0 +1,67 @@
+#[test]
+fn do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node00 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(100f32),
+                height: taffy::style::Dimension::Points(100f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node0 = taffy
+        .new_with_children(
+            taffy::style::Style {
+                position: taffy::style::Position::Absolute,
+                flex_direction: taffy::style::FlexDirection::Column,
+                inset: taffy::geometry::Rect {
+                    left: taffy::style::LengthPercentageAuto::Points(0f32),
+                    right: auto(),
+                    top: taffy::style::LengthPercentageAuto::Points(0f32),
+                    bottom: auto(),
+                },
+                ..Default::default()
+            },
+            &[node00],
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(50f32),
+                },
+                ..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, 50f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, 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, 100f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node00).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node00.data(), 100f32, size.width);
+    assert_eq!(size.height, 100f32, "height of node {:?}. Expected {}. Actual {}", node00.data(), 100f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node00.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node00.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_fit_content_percent_indefinite_max_content_hidden.rs b/tests/generated/grid_fit_content_percent_indefinite_max_content_hidden.rs
new file mode 100644
index 000000000..04fe10b89
--- /dev/null
+++ b/tests/generated/grid_fit_content_percent_indefinite_max_content_hidden.rs
@@ -0,0 +1,53 @@
+#[test]
+fn grid_fit_content_percent_indefinite_max_content_hidden() {
+    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 {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                ..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, 10f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 10f32, 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_hidden.rs b/tests/generated/grid_fit_content_percent_indefinite_min_content_hidden.rs
new file mode 100644
index 000000000..bac384717
--- /dev/null
+++ b/tests/generated/grid_fit_content_percent_indefinite_min_content_hidden.rs
@@ -0,0 +1,53 @@
+#[test]
+fn grid_fit_content_percent_indefinite_min_content_hidden() {
+    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 {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                ..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, 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_points_min_content_hidden.rs b/tests/generated/grid_fit_content_points_min_content_hidden.rs
new file mode 100644
index 000000000..f1569f365
--- /dev/null
+++ b/tests/generated/grid_fit_content_points_min_content_hidden.rs
@@ -0,0 +1,53 @@
+#[test]
+fn grid_fit_content_points_min_content_hidden() {
+    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 {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                ..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(points(30f32))],
+                ..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, 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, 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_overflow_inline_axis_hidden.rs b/tests/generated/grid_overflow_inline_axis_hidden.rs
new file mode 100644
index 000000000..64c40045b
--- /dev/null
+++ b/tests/generated/grid_overflow_inline_axis_hidden.rs
@@ -0,0 +1,55 @@
+#[test]
+fn grid_overflow_inline_axis_hidden() {
+    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 {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHHHHHHHH";
+                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,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(50f32),
+                },
+                ..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, 50f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_overflow_inline_axis_visible.rs b/tests/generated/grid_overflow_inline_axis_visible.rs
new file mode 100644
index 000000000..8e6255fd7
--- /dev/null
+++ b/tests/generated/grid_overflow_inline_axis_visible.rs
@@ -0,0 +1,49 @@
+#[test]
+fn grid_overflow_inline_axis_visible() {
+    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 = "HHHHHHHHHH";
+                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,
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(50f32),
+                },
+                ..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, 50f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, 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, 100f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 100f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_percent_items_nested_moderate.rs b/tests/generated/grid_percent_items_nested_moderate.rs
index 80e3a8214..da361ae74 100644
--- a/tests/generated/grid_percent_items_nested_moderate.rs
+++ b/tests/generated/grid_percent_items_nested_moderate.rs
@@ -89,10 +89,10 @@ fn grid_percent_items_nested_moderate() {
     assert!(location.y - 8f32 < 0.1, "y of node {:?}. Expected {}. Actual {}", node0.data(), 8f32, location.y);
     let Layout { size, location, .. } = taffy.layout(node00).unwrap();
     assert!(
-        size.width - 38.40625f32 < 0.1,
+        size.width - 38.414063f32 < 0.1,
         "width of node {:?}. Expected {}. Actual {}",
         node00.data(),
-        38.40625f32,
+        38.414063f32,
         size.width
     );
     assert!(size.height - 6f32 < 0.1, "height of node {:?}. Expected {}. Actual {}", node00.data(), 6f32, size.height);
diff --git a/tests/generated/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.rs b/tests/generated/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.rs
new file mode 100644
index 000000000..d8bd307e3
--- /dev/null
+++ b/tests/generated/grid_span_13_most_non_flex_with_minmax_indefinite_hidden.rs
@@ -0,0 +1,146 @@
+#[test]
+fn grid_span_13_most_non_flex_with_minmax_indefinite_hidden() {
+    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 {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(13u16) },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHHHHHHHHHHHHHH\u{200b}HHHHHHHHHHHHHHHH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).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 node9 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node10 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node11 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node12 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap();
+    let node13 = 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)],
+                grid_template_columns: vec![
+                    min_content(),
+                    max_content(),
+                    fit_content(points(20f32)),
+                    auto(),
+                    points(10f32),
+                    percent(0.2f32),
+                    minmax(points(2f32), auto()),
+                    minmax(points(2f32), points(4f32)),
+                    minmax(points(2f32), min_content()),
+                    minmax(points(2f32), max_content()),
+                    minmax(min_content(), max_content()),
+                    minmax(min_content(), auto()),
+                    minmax(max_content(), auto()),
+                ],
+                ..Default::default()
+            },
+            &[node0, node1, node2, node3, node4, node5, node6, node7, node8, node9, node10, node11, node12, node13],
+        )
+        .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, 322f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 322f32, size.width);
+    assert_eq!(size.height, 80f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 80f32, 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, 322f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 322f32, 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, 16f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 16f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+    assert_eq!(size.width, 95f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 95f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+    assert_eq!(location.x, 16f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 16f32, 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, 0f32, "width of node {:?}. Expected {}. Actual {}", node3.data(), 0f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.height);
+    assert_eq!(location.x, 111f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 111f32, 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, 0f32, "width of node {:?}. Expected {}. Actual {}", node4.data(), 0f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, size.height);
+    assert_eq!(location.x, 111f32, "x of node {:?}. Expected {}. Actual {}", node4.data(), 111f32, 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, 10f32, "width of node {:?}. Expected {}. Actual {}", node5.data(), 10f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.height);
+    assert_eq!(location.x, 111f32, "x of node {:?}. Expected {}. Actual {}", node5.data(), 111f32, 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, 64f32, "width of node {:?}. Expected {}. Actual {}", node6.data(), 64f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.height);
+    assert_eq!(location.x, 121f32, "x of node {:?}. Expected {}. Actual {}", node6.data(), 121f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node7).unwrap();
+    assert_eq!(size.width, 2f32, "width of node {:?}. Expected {}. Actual {}", node7.data(), 2f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, size.height);
+    assert_eq!(location.x, 185f32, "x of node {:?}. Expected {}. Actual {}", node7.data(), 185f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node7.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node8).unwrap();
+    assert_eq!(size.width, 4f32, "width of node {:?}. Expected {}. Actual {}", node8.data(), 4f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, size.height);
+    assert_eq!(location.x, 187f32, "x of node {:?}. Expected {}. Actual {}", node8.data(), 187f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node8.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node9).unwrap();
+    assert_eq!(size.width, 2f32, "width of node {:?}. Expected {}. Actual {}", node9.data(), 2f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node9.data(), 40f32, size.height);
+    assert_eq!(location.x, 191f32, "x of node {:?}. Expected {}. Actual {}", node9.data(), 191f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node9.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node10).unwrap();
+    assert_eq!(size.width, 2f32, "width of node {:?}. Expected {}. Actual {}", node10.data(), 2f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node10.data(), 40f32, size.height);
+    assert_eq!(location.x, 193f32, "x of node {:?}. Expected {}. Actual {}", node10.data(), 193f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node10.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node11).unwrap();
+    assert_eq!(size.width, 16f32, "width of node {:?}. Expected {}. Actual {}", node11.data(), 16f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node11.data(), 40f32, size.height);
+    assert_eq!(location.x, 195f32, "x of node {:?}. Expected {}. Actual {}", node11.data(), 195f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node11.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node12).unwrap();
+    assert_eq!(size.width, 15f32, "width of node {:?}. Expected {}. Actual {}", node12.data(), 15f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node12.data(), 40f32, size.height);
+    assert_eq!(location.x, 211f32, "x of node {:?}. Expected {}. Actual {}", node12.data(), 211f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node12.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node13).unwrap();
+    assert_eq!(size.width, 96f32, "width of node {:?}. Expected {}. Actual {}", node13.data(), 96f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node13.data(), 40f32, size.height);
+    assert_eq!(location.x, 226f32, "x of node {:?}. Expected {}. Actual {}", node13.data(), 226f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node13.data(), 40f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_max_content_auto_indefinite_hidden.rs b/tests/generated/grid_span_2_max_content_auto_indefinite_hidden.rs
new file mode 100644
index 000000000..963d4e55d
--- /dev/null
+++ b/tests/generated/grid_span_2_max_content_auto_indefinite_hidden.rs
@@ -0,0 +1,51 @@
+#[test]
+fn grid_span_2_max_content_auto_indefinite_hidden() {
+    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 {
+            grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_leaf(taffy::style::Style {
+            grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            grid_column: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+            ..Default::default()
+        })
+        .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![max_content(), auto()],
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 0f32, 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, 0f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, 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, 0f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_max_content_fit_content_10px_indefinite_hidden.rs b/tests/generated/grid_span_2_max_content_fit_content_10px_indefinite_hidden.rs
new file mode 100644
index 000000000..27dc3e801
--- /dev/null
+++ b/tests/generated/grid_span_2_max_content_fit_content_10px_indefinite_hidden.rs
@@ -0,0 +1,79 @@
+#[test]
+fn grid_span_2_max_content_fit_content_10px_indefinite_hidden() {
+    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 {
+            grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_leaf(taffy::style::Style {
+            grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            grid_column: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+                grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(2u16) },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHH\u{200b}HHHH";
+                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![max_content(), fit_content(points(10f32))],
+                ..Default::default()
+            },
+            &[node0, node1, node2],
+        )
+        .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, 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, 80f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 80f32, 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, 0f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+    assert_eq!(location.x, 80f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 80f32, 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, 80f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 80f32, 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, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_max_content_fit_content_80px_indefinite_hidden.rs b/tests/generated/grid_span_2_max_content_fit_content_80px_indefinite_hidden.rs
new file mode 100644
index 000000000..8daf9a8a8
--- /dev/null
+++ b/tests/generated/grid_span_2_max_content_fit_content_80px_indefinite_hidden.rs
@@ -0,0 +1,79 @@
+#[test]
+fn grid_span_2_max_content_fit_content_80px_indefinite_hidden() {
+    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 {
+            grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_leaf(taffy::style::Style {
+            grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            grid_column: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+                grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(2u16) },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHH\u{200b}HHHH";
+                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![max_content(), fit_content(points(80f32))],
+                ..Default::default()
+            },
+            &[node0, node1, node2],
+        )
+        .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, 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, 80f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 80f32, 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, 0f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+    assert_eq!(location.x, 80f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 80f32, 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, 80f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 80f32, 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, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_min_content_auto_indefinite_hidden.rs b/tests/generated/grid_span_2_min_content_auto_indefinite_hidden.rs
new file mode 100644
index 000000000..92b1a421a
--- /dev/null
+++ b/tests/generated/grid_span_2_min_content_auto_indefinite_hidden.rs
@@ -0,0 +1,66 @@
+#[test]
+fn grid_span_2_min_content_auto_indefinite_hidden() {
+    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(taffy::style::Style { ..Default::default() }).unwrap();
+    let node2 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(2u16) },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHH\u{200b}HHHH";
+                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![min_content(), auto()],
+                ..Default::default()
+            },
+            &[node0, node1, node2],
+        )
+        .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, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, 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, 80f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 80f32, size.width);
+    assert_eq!(size.height, 10f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 10f32, 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);
+}
diff --git a/tests/generated/grid_span_2_min_content_fit_content_10px_indefinite_hidden.rs b/tests/generated/grid_span_2_min_content_fit_content_10px_indefinite_hidden.rs
new file mode 100644
index 000000000..8ebbf29fc
--- /dev/null
+++ b/tests/generated/grid_span_2_min_content_fit_content_10px_indefinite_hidden.rs
@@ -0,0 +1,79 @@
+#[test]
+fn grid_span_2_min_content_fit_content_10px_indefinite_hidden() {
+    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 {
+            grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_leaf(taffy::style::Style {
+            grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            grid_column: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+                grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(2u16) },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHH\u{200b}HHHH";
+                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![min_content(), fit_content(points(10f32))],
+                ..Default::default()
+            },
+            &[node0, node1, node2],
+        )
+        .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, 50f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 50f32, 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);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 10f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 10f32, 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, 50f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 50f32, 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, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_min_content_fit_content_30px_indefinite_hidden.rs b/tests/generated/grid_span_2_min_content_fit_content_30px_indefinite_hidden.rs
new file mode 100644
index 000000000..418447df7
--- /dev/null
+++ b/tests/generated/grid_span_2_min_content_fit_content_30px_indefinite_hidden.rs
@@ -0,0 +1,79 @@
+#[test]
+fn grid_span_2_min_content_fit_content_30px_indefinite_hidden() {
+    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 {
+            grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_leaf(taffy::style::Style {
+            grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            grid_column: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+                grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(2u16) },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHH\u{200b}HHHH";
+                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![min_content(), fit_content(points(30f32))],
+                ..Default::default()
+            },
+            &[node0, node1, node2],
+        )
+        .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, 70f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 70f32, 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);
+    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, 70f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 70f32, 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, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_span_2_min_content_fit_content_80px_indefinite_hidden.rs b/tests/generated/grid_span_2_min_content_fit_content_80px_indefinite_hidden.rs
new file mode 100644
index 000000000..4f5d0c7c8
--- /dev/null
+++ b/tests/generated/grid_span_2_min_content_fit_content_80px_indefinite_hidden.rs
@@ -0,0 +1,79 @@
+#[test]
+fn grid_span_2_min_content_fit_content_80px_indefinite_hidden() {
+    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 {
+            grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_leaf(taffy::style::Style {
+            grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+            grid_column: taffy::geometry::Line { start: line(2i16), end: taffy::style::GridPlacement::Auto },
+            ..Default::default()
+        })
+        .unwrap();
+    let node2 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                grid_row: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Auto },
+                grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(2u16) },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHH\u{200b}HHHH";
+                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![min_content(), fit_content(points(80f32))],
+                ..Default::default()
+            },
+            &[node0, node1, node2],
+        )
+        .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, 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);
+    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, 80f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 80f32, 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, 0f32, "y of node {:?}. Expected {}. Actual {}", node2.data(), 0f32, location.y);
+}
diff --git a/tests/generated/grid_span_6_all_non_flex_indefinite_hidden.rs b/tests/generated/grid_span_6_all_non_flex_indefinite_hidden.rs
new file mode 100644
index 000000000..3ef4b3a54
--- /dev/null
+++ b/tests/generated/grid_span_6_all_non_flex_indefinite_hidden.rs
@@ -0,0 +1,97 @@
+#[test]
+fn grid_span_6_all_non_flex_indefinite_hidden() {
+    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 {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                grid_column: taffy::geometry::Line { start: line(1i16), end: taffy::style::GridPlacement::Span(6u16) },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHHHHHH\u{200b}HHHHHHHH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node1 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).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 node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                display: taffy::style::Display::Grid,
+                grid_template_rows: vec![points(40f32), points(40f32)],
+                grid_template_columns: vec![
+                    min_content(),
+                    max_content(),
+                    fit_content(points(20f32)),
+                    auto(),
+                    points(10f32),
+                    percent(0.2f32),
+                ],
+                ..Default::default()
+            },
+            &[node0, node1, node2, node3, node4, node5, node6],
+        )
+        .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, 160f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 160f32, size.width);
+    assert_eq!(size.height, 80f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 80f32, 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, 160f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 160f32, 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, 19f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 19f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 40f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node2).unwrap();
+    assert_eq!(size.width, 99f32, "width of node {:?}. Expected {}. Actual {}", node2.data(), 99f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node2.data(), 40f32, size.height);
+    assert_eq!(location.x, 19f32, "x of node {:?}. Expected {}. Actual {}", node2.data(), 19f32, 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, 0f32, "width of node {:?}. Expected {}. Actual {}", node3.data(), 0f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node3.data(), 40f32, size.height);
+    assert_eq!(location.x, 118f32, "x of node {:?}. Expected {}. Actual {}", node3.data(), 118f32, 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, 0f32, "width of node {:?}. Expected {}. Actual {}", node4.data(), 0f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node4.data(), 40f32, size.height);
+    assert_eq!(location.x, 118f32, "x of node {:?}. Expected {}. Actual {}", node4.data(), 118f32, 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, 10f32, "width of node {:?}. Expected {}. Actual {}", node5.data(), 10f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node5.data(), 40f32, size.height);
+    assert_eq!(location.x, 118f32, "x of node {:?}. Expected {}. Actual {}", node5.data(), 118f32, 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, 32f32, "width of node {:?}. Expected {}. Actual {}", node6.data(), 32f32, size.width);
+    assert_eq!(size.height, 40f32, "height of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, size.height);
+    assert_eq!(location.x, 128f32, "x of node {:?}. Expected {}. Actual {}", node6.data(), 128f32, location.x);
+    assert_eq!(location.y, 40f32, "y of node {:?}. Expected {}. Actual {}", node6.data(), 40f32, location.y);
+}
diff --git a/tests/generated/measure_child_with_flex_shrink_hidden.rs b/tests/generated/measure_child_with_flex_shrink_hidden.rs
new file mode 100644
index 000000000..7a5d9c049
--- /dev/null
+++ b/tests/generated/measure_child_with_flex_shrink_hidden.rs
@@ -0,0 +1,68 @@
+#[test]
+fn measure_child_with_flex_shrink_hidden() {
+    use slotmap::Key;
+    #[allow(unused_imports)]
+    use taffy::{layout::Layout, prelude::*};
+    let mut taffy = taffy::Taffy::new();
+    let node0 = taffy
+        .new_leaf(taffy::style::Style {
+            size: taffy::geometry::Size {
+                width: taffy::style::Dimension::Points(50f32),
+                height: taffy::style::Dimension::Points(50f32),
+            },
+            ..Default::default()
+        })
+        .unwrap();
+    let node1 = taffy
+        .new_leaf_with_measure(
+            taffy::style::Style {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHHHHHHHH\u{200b}HHHHHHHHHH\u{200b}HHHHHHHHHH\u{200b}HHHHHHHHHH\u{200b}HHHHHHHHHH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(100f32),
+                    height: taffy::style::Dimension::Auto,
+                },
+                ..Default::default()
+            },
+            &[node0, node1],
+        )
+        .unwrap();
+    taffy.compute_layout(node, taffy::geometry::Size::MAX_CONTENT).unwrap();
+    println!("\nComputed tree:");
+    taffy::debug::print_tree(&taffy, node);
+    println!();
+    let Layout { size, location, .. } = taffy.layout(node).unwrap();
+    assert_eq!(size.width, 100f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 100f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, 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, 9f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 9f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node1).unwrap();
+    assert_eq!(size.width, 91f32, "width of node {:?}. Expected {}. Actual {}", node1.data(), 91f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node1.data(), 50f32, size.height);
+    assert_eq!(location.x, 9f32, "x of node {:?}. Expected {}. Actual {}", node1.data(), 9f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node1.data(), 0f32, location.y);
+}
diff --git a/tests/generated/mod.rs b/tests/generated/mod.rs
index 4be363806..748958cd5 100644
--- a/tests/generated/mod.rs
+++ b/tests/generated/mod.rs
@@ -222,6 +222,7 @@ mod display_none_with_child;
 mod display_none_with_margin;
 mod display_none_with_position;
 mod display_none_with_position_absolute;
+mod do_not_clamp_height_of_absolute_node_to_height_of_its_overflow_hidden_parent;
 mod flex_basis_and_main_dimen_set_when_flexing;
 mod flex_basis_flex_grow_column;
 mod flex_basis_flex_grow_row;
@@ -482,14 +483,20 @@ 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_max_content_hidden;
+#[cfg(feature = "grid")]
 mod grid_fit_content_percent_indefinite_min_content;
 #[cfg(feature = "grid")]
+mod grid_fit_content_percent_indefinite_min_content_hidden;
+#[cfg(feature = "grid")]
 mod grid_fit_content_points_argument;
 #[cfg(feature = "grid")]
 mod grid_fit_content_points_max_content;
 #[cfg(feature = "grid")]
 mod grid_fit_content_points_min_content;
 #[cfg(feature = "grid")]
+mod grid_fit_content_points_min_content_hidden;
+#[cfg(feature = "grid")]
 mod grid_fr_fixed_size_no_content_proportions;
 #[cfg(feature = "grid")]
 mod grid_fr_fixed_size_no_content_proportions_sub_1_sum;
@@ -650,6 +657,10 @@ mod grid_minmax_min_content_percent_indefinite;
 #[cfg(feature = "grid")]
 mod grid_out_of_order_items;
 #[cfg(feature = "grid")]
+mod grid_overflow_inline_axis_hidden;
+#[cfg(feature = "grid")]
+mod grid_overflow_inline_axis_visible;
+#[cfg(feature = "grid")]
 mod grid_overflow_rows;
 #[cfg(feature = "grid")]
 mod grid_padding_border_overrides_container_max_size;
@@ -702,28 +713,46 @@ mod grid_size_child_fixed_tracks;
 #[cfg(feature = "grid")]
 mod grid_span_13_most_non_flex_with_minmax_indefinite;
 #[cfg(feature = "grid")]
+mod grid_span_13_most_non_flex_with_minmax_indefinite_hidden;
+#[cfg(feature = "grid")]
 mod grid_span_2_max_content_auto_indefinite;
 #[cfg(feature = "grid")]
+mod grid_span_2_max_content_auto_indefinite_hidden;
+#[cfg(feature = "grid")]
 mod grid_span_2_max_content_fit_content_10px_indefinite;
 #[cfg(feature = "grid")]
+mod grid_span_2_max_content_fit_content_10px_indefinite_hidden;
+#[cfg(feature = "grid")]
 mod grid_span_2_max_content_fit_content_80px_indefinite;
 #[cfg(feature = "grid")]
+mod grid_span_2_max_content_fit_content_80px_indefinite_hidden;
+#[cfg(feature = "grid")]
 mod grid_span_2_max_content_max_content_indefinite;
 #[cfg(feature = "grid")]
 mod grid_span_2_min_content_auto_indefinite;
 #[cfg(feature = "grid")]
+mod grid_span_2_min_content_auto_indefinite_hidden;
+#[cfg(feature = "grid")]
 mod grid_span_2_min_content_fit_content_10px_indefinite;
 #[cfg(feature = "grid")]
+mod grid_span_2_min_content_fit_content_10px_indefinite_hidden;
+#[cfg(feature = "grid")]
 mod grid_span_2_min_content_fit_content_30px_indefinite;
 #[cfg(feature = "grid")]
+mod grid_span_2_min_content_fit_content_30px_indefinite_hidden;
+#[cfg(feature = "grid")]
 mod grid_span_2_min_content_fit_content_80px_indefinite;
 #[cfg(feature = "grid")]
+mod grid_span_2_min_content_fit_content_80px_indefinite_hidden;
+#[cfg(feature = "grid")]
 mod grid_span_2_min_content_max_content_indefinite;
 #[cfg(feature = "grid")]
 mod grid_span_2_min_content_min_content_indefinite;
 #[cfg(feature = "grid")]
 mod grid_span_6_all_non_flex_indefinite;
 #[cfg(feature = "grid")]
+mod grid_span_6_all_non_flex_indefinite_hidden;
+#[cfg(feature = "grid")]
 mod grid_span_8_all_track_types_indefinite;
 #[cfg(feature = "grid")]
 mod gridflex_column_integration;
@@ -812,6 +841,7 @@ mod measure_child_constraint;
 mod measure_child_constraint_padding_parent;
 mod measure_child_with_flex_grow;
 mod measure_child_with_flex_shrink;
+mod measure_child_with_flex_shrink_hidden;
 mod measure_child_with_min_size_greater_than_available_space;
 mod measure_flex_basis_overrides_measure;
 mod measure_height_overrides_measure;
@@ -839,6 +869,8 @@ mod nested_overflowing_child_in_constraint_parent;
 mod only_shrinkable_item_with_flex_basis_zero;
 mod overflow_cross_axis;
 mod overflow_main_axis;
+mod overflow_main_axis_shrink_hidden;
+mod overflow_main_axis_shrink_visible;
 mod padding_align_end_child;
 mod padding_border_overrides_max_size;
 mod padding_border_overrides_min_size;
diff --git a/tests/generated/overflow_main_axis_shrink_hidden.rs b/tests/generated/overflow_main_axis_shrink_hidden.rs
new file mode 100644
index 000000000..bed451012
--- /dev/null
+++ b/tests/generated/overflow_main_axis_shrink_hidden.rs
@@ -0,0 +1,55 @@
+#[test]
+fn overflow_main_axis_shrink_hidden() {
+    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 {
+                overflow: taffy::geometry::Point {
+                    x: taffy::style::Overflow::Hidden,
+                    y: taffy::style::Overflow::Hidden,
+                },
+                flex_shrink: 1f32,
+                ..Default::default()
+            },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHHHHHHHH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(50f32),
+                },
+                ..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, 50f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node.data(), 0f32, location.y);
+    let Layout { size, location, .. } = taffy.layout(node0).unwrap();
+    assert_eq!(size.width, 50f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+}
diff --git a/tests/generated/overflow_main_axis_shrink_visible.rs b/tests/generated/overflow_main_axis_shrink_visible.rs
new file mode 100644
index 000000000..171502e3d
--- /dev/null
+++ b/tests/generated/overflow_main_axis_shrink_visible.rs
@@ -0,0 +1,48 @@
+#[test]
+fn overflow_main_axis_shrink_visible() {
+    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 { flex_shrink: 1f32, ..Default::default() },
+            taffy::node::MeasureFunc::Raw(|known_dimensions, available_space| {
+                const TEXT: &str = "HHHHHHHHHH";
+                super::measure_standard_text(
+                    known_dimensions,
+                    available_space,
+                    TEXT,
+                    super::WritingMode::Horizontal,
+                    None,
+                )
+            }),
+        )
+        .unwrap();
+    let node = taffy
+        .new_with_children(
+            taffy::style::Style {
+                size: taffy::geometry::Size {
+                    width: taffy::style::Dimension::Points(50f32),
+                    height: taffy::style::Dimension::Points(50f32),
+                },
+                ..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, 50f32, "width of node {:?}. Expected {}. Actual {}", node.data(), 50f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node.data(), 50f32, 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, 100f32, "width of node {:?}. Expected {}. Actual {}", node0.data(), 100f32, size.width);
+    assert_eq!(size.height, 50f32, "height of node {:?}. Expected {}. Actual {}", node0.data(), 50f32, size.height);
+    assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.x);
+    assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node0.data(), 0f32, location.y);
+}
diff --git a/tests/generated/percentage_moderate_complexity.rs b/tests/generated/percentage_moderate_complexity.rs
index 7201b3956..0e93704d5 100644
--- a/tests/generated/percentage_moderate_complexity.rs
+++ b/tests/generated/percentage_moderate_complexity.rs
@@ -91,10 +91,10 @@ fn percentage_moderate_complexity() {
     assert!(location.y - 8f32 < 0.1, "y of node {:?}. Expected {}. Actual {}", node0.data(), 8f32, location.y);
     let Layout { size, location, .. } = taffy.layout(node00).unwrap();
     assert!(
-        size.width - 38.40625f32 < 0.1,
+        size.width - 38.414063f32 < 0.1,
         "width of node {:?}. Expected {}. Actual {}",
         node00.data(),
-        38.40625f32,
+        38.414063f32,
         size.width
     );
     assert!(size.height - 6f32 < 0.1, "height of node {:?}. Expected {}. Actual {}", node00.data(), 6f32, size.height);