diff --git a/RELEASES.md b/RELEASES.md index 811ec88f9..c76236dda 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -5,6 +5,7 @@ ### Fixes - Content alignment (`align-content`/`justify-content`) behaviour was updated to match the latest spec (and Chrome 123+) (#635) +- Ensure that root Flexbox nodes are floored by their padding-border (#651, #655) ## 0.4.3 diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs index 94eb74927..464cd0a91 100644 --- a/src/compute/flexbox.rs +++ b/src/compute/flexbox.rs @@ -1,6 +1,4 @@ //! Computes the [flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) layout algorithm on [`TaffyTree`](crate::TaffyTree) according to the [spec](https://www.w3.org/TR/css-flexbox-1/) -use core::ops::Add; - use crate::compute::common::alignment::compute_alignment_offset; use crate::geometry::{Line, Point, Rect, Size}; use crate::style::{ @@ -163,6 +161,9 @@ pub fn compute_flexbox_layout(tree: &mut impl LayoutPartialTree, node: NodeId, i let aspect_ratio = style.aspect_ratio; let min_size = style.min_size.maybe_resolve(parent_size).maybe_apply_aspect_ratio(aspect_ratio); let max_size = style.max_size.maybe_resolve(parent_size).maybe_apply_aspect_ratio(aspect_ratio); + let padding = style.padding.resolve_or_zero(parent_size.width); + let border = style.border.resolve_or_zero(parent_size.width); + let padding_border_sum = padding.sum_axes() + border.sum_axes(); let clamped_style_size = if inputs.sizing_mode == SizingMode::InherentSize { style.size.maybe_resolve(parent_size).maybe_apply_aspect_ratio(aspect_ratio).maybe_clamp(min_size, max_size) } else { @@ -175,16 +176,9 @@ pub fn compute_flexbox_layout(tree: &mut impl LayoutPartialTree, node: NodeId, i _ => None, }); - // if the sum of the padding and border is greater than the size of the container, the - // the result overwrites the size of the container - let padding_border_sum = style - .padding - .resolve_or_zero(parent_size.width) - .sum_axes() - .add(style.border.resolve_or_zero(parent_size.width).sum_axes()); - + // The size of the container should be floored by the padding and border let styled_based_known_dimensions = - known_dimensions.or(min_max_definite_size).or(clamped_style_size).maybe_max(padding_border_sum); + known_dimensions.or(min_max_definite_size.or(clamped_style_size).maybe_max(padding_border_sum)); // Short-circuit layout if the container's size is fully determined by the container's size and the run mode // is ComputeSize (and thus the container's size is all that we're interested in) @@ -2185,10 +2179,9 @@ mod tests { use crate::{ geometry::Size, - prelude::{length, TaffyMaxContent}, style::{FlexWrap, Style}, util::{MaybeMath, ResolveOrZero}, - Rect, TaffyTree, + TaffyTree, }; // Make sure we get correct constants @@ -2227,31 +2220,4 @@ mod tests { assert_eq!(constants.container_size, Size::zero()); assert_eq!(constants.inner_container_size, Size::zero()); } - - #[test] - pub fn test_padding_and_border_larger_than_definite_size() { - let mut tree: TaffyTree<()> = TaffyTree::with_capacity(16); - - let child = tree.new_leaf(Style::default()).unwrap(); - - let root = tree - .new_with_children( - Style { - size: Size { width: length(10.0), height: length(10.0) }, - padding: Rect { left: length(10.0), right: length(10.0), top: length(10.0), bottom: length(10.0) }, - - border: Rect { left: length(10.0), right: length(10.0), top: length(10.0), bottom: length(10.0) }, - ..Default::default() - }, - &[child], - ) - .unwrap(); - - tree.compute_layout(root, Size::MAX_CONTENT).unwrap(); - - let layout = tree.layout(root).unwrap(); - - assert_eq!(layout.size.width, 40.0); - assert_eq!(layout.size.height, 40.0); - } } diff --git a/test_fixtures/flex/padding_border_overrides_size_root.html b/test_fixtures/flex/padding_border_overrides_size_root.html new file mode 100644 index 000000000..9dbcfe951 --- /dev/null +++ b/test_fixtures/flex/padding_border_overrides_size_root.html @@ -0,0 +1,17 @@ + + + + + + + Test description + + + + +
+
+
+ + + \ No newline at end of file diff --git a/tests/generated/flex/mod.rs b/tests/generated/flex/mod.rs index 6e427742d..b2f6d34c4 100644 --- a/tests/generated/flex/mod.rs +++ b/tests/generated/flex/mod.rs @@ -425,6 +425,7 @@ mod padding_border_overrides_min_size; mod padding_border_overrides_size; mod padding_border_overrides_size_flex_basis_0; mod padding_border_overrides_size_flex_basis_0_growable; +mod padding_border_overrides_size_root; mod padding_center_child; mod padding_container_match_child; mod padding_flex_child; diff --git a/tests/generated/flex/padding_border_overrides_size_root.rs b/tests/generated/flex/padding_border_overrides_size_root.rs new file mode 100644 index 000000000..33f2844fb --- /dev/null +++ b/tests/generated/flex/padding_border_overrides_size_root.rs @@ -0,0 +1,83 @@ +#[test] +fn padding_border_overrides_size_root() { + #[allow(unused_imports)] + use taffy::{prelude::*, tree::Layout, TaffyTree}; + let mut taffy: TaffyTree = TaffyTree::new(); + let node0 = taffy.new_leaf(taffy::style::Style { ..Default::default() }).unwrap(); + let node = taffy + .new_with_children( + taffy::style::Style { + size: taffy::geometry::Size { + width: taffy::style::Dimension::Length(12f32), + height: taffy::style::Dimension::Length(12f32), + }, + padding: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Length(8f32), + right: taffy::style::LengthPercentage::Length(4f32), + top: taffy::style::LengthPercentage::Length(2f32), + bottom: taffy::style::LengthPercentage::Length(6f32), + }, + border: taffy::geometry::Rect { + left: taffy::style::LengthPercentage::Length(7f32), + right: taffy::style::LengthPercentage::Length(3f32), + top: taffy::style::LengthPercentage::Length(1f32), + bottom: taffy::style::LengthPercentage::Length(5f32), + }, + ..Default::default() + }, + &[node0], + ) + .unwrap(); + taffy.compute_layout_with_measure(node, taffy::geometry::Size::MAX_CONTENT, crate::test_measure_function).unwrap(); + println!("\nComputed tree:"); + taffy.print_tree(node); + println!(); + #[cfg_attr(not(feature = "content_size"), allow(unused_variables))] + let layout @ Layout { size, location, .. } = taffy.layout(node).unwrap(); + assert_eq!(size.width, 22f32, "width of node {:?}. Expected {}. Actual {}", node, 22f32, size.width); + assert_eq!(size.height, 14f32, "height of node {:?}. Expected {}. Actual {}", node, 14f32, size.height); + assert_eq!(location.x, 0f32, "x of node {:?}. Expected {}. Actual {}", node, 0f32, location.x); + assert_eq!(location.y, 0f32, "y of node {:?}. Expected {}. Actual {}", node, 0f32, location.y); + #[cfg(feature = "content_size")] + assert_eq!( + layout.scroll_width(), + 0f32, + "scroll_width of node {:?}. Expected {}. Actual {}", + node, + 0f32, + layout.scroll_width() + ); + #[cfg(feature = "content_size")] + assert_eq!( + layout.scroll_height(), + 0f32, + "scroll_height of node {:?}. Expected {}. Actual {}", + node, + 0f32, + layout.scroll_height() + ); + #[cfg_attr(not(feature = "content_size"), allow(unused_variables))] + let layout @ Layout { size, location, .. } = taffy.layout(node0).unwrap(); + assert_eq!(size.width, 0f32, "width of node {:?}. Expected {}. Actual {}", node0, 0f32, size.width); + assert_eq!(size.height, 0f32, "height of node {:?}. Expected {}. Actual {}", node0, 0f32, size.height); + assert_eq!(location.x, 15f32, "x of node {:?}. Expected {}. Actual {}", node0, 15f32, location.x); + assert_eq!(location.y, 3f32, "y of node {:?}. Expected {}. Actual {}", node0, 3f32, location.y); + #[cfg(feature = "content_size")] + assert_eq!( + layout.scroll_width(), + 0f32, + "scroll_width of node {:?}. Expected {}. Actual {}", + node0, + 0f32, + layout.scroll_width() + ); + #[cfg(feature = "content_size")] + assert_eq!( + layout.scroll_height(), + 0f32, + "scroll_height of node {:?}. Expected {}. Actual {}", + node0, + 0f32, + layout.scroll_height() + ); +} diff --git a/tests/root_constraints.rs b/tests/root_constraints.rs index 9216118d2..631751d48 100644 --- a/tests/root_constraints.rs +++ b/tests/root_constraints.rs @@ -1,7 +1,7 @@ #[cfg(test)] mod root_constraints { - use taffy::style::AvailableSpace; - use taffy::TaffyTree; + use taffy::style_helpers::{length, TaffyMaxContent}; + use taffy::{AvailableSpace, Rect, Size, Style, TaffyTree}; #[test] fn root_with_percentage_size() { @@ -78,4 +78,31 @@ mod root_constraints { assert_eq!(layout.size.width, 200.0); assert_eq!(layout.size.height, 200.0); } + + #[test] + fn root_padding_and_border_larger_than_definite_size() { + let mut tree: TaffyTree<()> = TaffyTree::with_capacity(16); + + let child = tree.new_leaf(Style::default()).unwrap(); + + let root = tree + .new_with_children( + Style { + size: Size { width: length(10.0), height: length(10.0) }, + padding: Rect { left: length(10.0), right: length(10.0), top: length(10.0), bottom: length(10.0) }, + + border: Rect { left: length(10.0), right: length(10.0), top: length(10.0), bottom: length(10.0) }, + ..Default::default() + }, + &[child], + ) + .unwrap(); + + tree.compute_layout(root, Size::MAX_CONTENT).unwrap(); + + let layout = tree.layout(root).unwrap(); + + assert_eq!(layout.size.width, 40.0); + assert_eq!(layout.size.height, 40.0); + } }