Ensure that root flexbox node sizes are floored by their padding border (#655)
* Uses the sum of border and padding if it's greater than the containers definite size
* Ensure that root flexbox node sizes are floored by their padding border
Co-authored-by: Julia Ortiz <contato@juliaortiz.com.br>
---------
Co-authored-by: Julia Ortiz <contato@juliaortiz.com.br>
c154b8aa719da0d6f8636b123765a47fa40a3306 · by Nico Burns · 2024-05-14T13:45:05Z (2 years ago) · parent 04e20d1de · browse the tree at this commit
Semantic delta · 4
tests/generated/flex/mod.rs
tests/generated/flex/padding_border_overrides_size_root.rs
tests/root_constraints.rs
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 592b8ec20..464cd0a91 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -161,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 {
@@ -172,7 +175,10 @@ pub fn compute_flexbox_layout(tree: &mut impl LayoutPartialTree, node: NodeId, i
(Some(min), Some(max)) if max <= min => Some(min),
_ => None,
});
- let styled_based_known_dimensions = known_dimensions.or(min_max_definite_size).or(clamped_style_size);
+
+ // 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));
// 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)
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 @@
+<!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: 12px; height: 12px; padding: 2px 4px 6px 8px; border-width: 1px 3px 5px 7px; border-style: solid; border-color: red;">
+ <div></div>
+</div>
+
+</body>
+</html>
\ 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<crate::TextMeasure> = 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);
+ }
}