Semántico sayk'uy · 10
benches/src/taffy_03_helpers.rs
benches/src/yoga_helpers.rs
src/style/mod.rs
- silq'uyninpi t'ikrakurqan enum Display pub
- ukhunpi t'ikrakurqan fn fmt
tests/hand_written/flow_root.rs
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a479e60ce..907cbd1fe 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
## Unreleased
+### Added
+
+- Support for `display: flow-root`. The new `Display::FlowRoot` variant lays out children using the block layout algorithm but always establishes a new block formatting context (its margins do not collapse with those of its children, it contains its own floats, and it avoids external floats)
+
### Fixed
- Numeric style helpers (`length`, `percent`, `fr`, `flex`) now accept `Input: Into<f64>` instead of `Input: Into<f32>`. This allows bare float literals such as `length(800.0)` to be used without triggering the `float_literal_f32_fallback` future-compatibility lint, while widening the set of accepted numeric input types (#974)
diff --git a/benches/src/taffy_03_helpers.rs b/benches/src/taffy_03_helpers.rs
index 8ab461178..c93bd214f 100644
--- a/benches/src/taffy_03_helpers.rs
+++ b/benches/src/taffy_03_helpers.rs
@@ -154,6 +154,7 @@ fn convert_display(input: taffy::style::Display) -> taffy_03::style::Display {
taffy::style::Display::Flex => taffy_03::style::Display::Flex,
taffy::style::Display::Grid => taffy_03::style::Display::Grid,
taffy::style::Display::Block => panic!("Block layout not implemented in taffy 0.3"),
+ taffy::style::Display::FlowRoot => panic!("Block layout not implemented in taffy 0.3"),
}
}
diff --git a/benches/src/yoga_helpers.rs b/benches/src/yoga_helpers.rs
index 9f61c34ae..586767ded 100644
--- a/benches/src/yoga_helpers.rs
+++ b/benches/src/yoga_helpers.rs
@@ -188,6 +188,7 @@ fn apply_taffy_style(node: &mut yg::Node, style: &tf::Style) {
tf::Display::Flex => yg::Display::Flex,
tf::Display::Grid => panic!("Yoga does not support CSS Grid layout"),
tf::Display::Block => panic!("Yoga does not support CSS Block layout"),
+ tf::Display::FlowRoot => panic!("Yoga does not support CSS Block layout"),
});
// box_sizing
diff --git a/src/style/mod.rs b/src/style/mod.rs
index beba85251..bf349e5c6 100644
--- a/src/style/mod.rs
+++ b/src/style/mod.rs
@@ -185,6 +185,9 @@ pub enum Display {
/// The children will follow the block layout algorithm
#[cfg(feature = "block_layout")]
Block,
+ /// The children will follow the block layout algorithm and establish a new block formatting context
+ #[cfg(feature = "block_layout")]
+ FlowRoot,
/// The children will follow the flexbox layout algorithm
#[cfg(feature = "flexbox")]
Flex,
@@ -228,6 +231,8 @@ crate::util::parse::impl_parse_for_keyword_enum!(Display,
"grid" => Grid,
#[cfg(feature = "block_layout")]
"block" => Block,
+ #[cfg(feature = "block_layout")]
+ "flow-root" => FlowRoot,
);
impl core::fmt::Display for Display {
@@ -236,6 +241,8 @@ impl core::fmt::Display for Display {
Display::None => write!(f, "NONE"),
#[cfg(feature = "block_layout")]
Display::Block => write!(f, "BLOCK"),
+ #[cfg(feature = "block_layout")]
+ Display::FlowRoot => write!(f, "FLOW-ROOT"),
#[cfg(feature = "flexbox")]
Display::Flex => write!(f, "FLEX"),
#[cfg(feature = "grid")]
diff --git a/src/tree/taffy_tree.rs b/src/tree/taffy_tree.rs
index ab9beb038..71a9fa735 100644
--- a/src/tree/taffy_tree.rs
+++ b/src/tree/taffy_tree.rs
@@ -236,6 +236,8 @@ impl<NodeContext> PrintTree for TaffyTree<NodeContext> {
(0, _) => "LEAF",
#[cfg(feature = "block_layout")]
(_, Display::Block) => "BLOCK",
+ #[cfg(feature = "block_layout")]
+ (_, Display::FlowRoot) => "FLOW-ROOT",
#[cfg(feature = "flexbox")]
(_, Display::Flex) => {
use crate::FlexDirection;
@@ -311,6 +313,8 @@ where
(Display::None, _) => compute_hidden_layout(tree, node_id),
#[cfg(feature = "block_layout")]
(Display::Block, true) => compute_block_layout(tree, node_id, inputs, block_ctx),
+ #[cfg(feature = "block_layout")]
+ (Display::FlowRoot, true) => compute_block_layout(tree, node_id, inputs, None),
#[cfg(feature = "flexbox")]
(Display::Flex, true) => compute_flexbox_layout(tree, node_id, inputs),
#[cfg(feature = "grid")]
diff --git a/tests/hand_written.rs b/tests/hand_written.rs
index 8f1b996ee..55caf68fa 100644
--- a/tests/hand_written.rs
+++ b/tests/hand_written.rs
@@ -2,6 +2,7 @@ mod hand_written {
mod border_and_padding;
mod caching;
mod floats;
+ mod flow_root;
mod measure;
mod min_max_overrides;
mod relayout;
diff --git a/tests/hand_written/flow_root.rs b/tests/hand_written/flow_root.rs
new file mode 100644
index 000000000..4e4288b5b
--- /dev/null
+++ b/tests/hand_written/flow_root.rs
@@ -0,0 +1,117 @@
+#![cfg(all(feature = "block_layout", feature = "float_layout"))]
+
+use taffy::geometry::{Point, Rect, Size};
+use taffy::prelude::*;
+use taffy::style::Float;
+use taffy_test_helpers::new_test_tree;
+
+#[test]
+fn flow_root_does_not_collapse_margins_through_parent() {
+ let child_style = Style {
+ display: Display::Block,
+ size: Size { width: length(40.0), height: length(10.0) },
+ margin: Rect { top: length(20.0), bottom: length(30.0), ..Rect::zero() },
+ ..Default::default()
+ };
+
+ let mut taffy = new_test_tree();
+ let plain_child = taffy.new_leaf(child_style.clone()).unwrap();
+ let plain_parent = taffy
+ .new_with_children(
+ Style {
+ display: Display::Block,
+ size: Size { width: length(100.0), height: auto() },
+ ..Default::default()
+ },
+ &[plain_child],
+ )
+ .unwrap();
+
+ let flow_child = taffy.new_leaf(child_style).unwrap();
+ let flow_parent = taffy
+ .new_with_children(
+ Style {
+ display: Display::FlowRoot,
+ size: Size { width: length(100.0), height: auto() },
+ ..Default::default()
+ },
+ &[flow_child],
+ )
+ .unwrap();
+ let root = taffy
+ .new_with_children(
+ Style {
+ display: Display::Block,
+ size: Size { width: length(200.0), height: auto() },
+ ..Default::default()
+ },
+ &[plain_parent, flow_parent],
+ )
+ .unwrap();
+ taffy.compute_layout(root, Size::MAX_CONTENT).unwrap();
+
+ assert_eq!(taffy.layout(plain_parent).unwrap().size.height, 10.0);
+ assert_eq!(taffy.layout(flow_parent).unwrap().size.height, 60.0);
+ assert_eq!(taffy.layout(flow_child).unwrap().location.y, 20.0);
+}
+
+#[test]
+fn flow_root_contains_floated_children() {
+ let mut taffy = new_test_tree();
+ let float = taffy
+ .new_leaf(Style {
+ display: Display::Block,
+ float: Float::Left,
+ size: Size { width: length(20.0), height: length(30.0) },
+ ..Default::default()
+ })
+ .unwrap();
+ let flow_root = taffy
+ .new_with_children(
+ Style {
+ display: Display::FlowRoot,
+ size: Size { width: length(100.0), height: auto() },
+ ..Default::default()
+ },
+ &[float],
+ )
+ .unwrap();
+ taffy.compute_layout(flow_root, Size::MAX_CONTENT).unwrap();
+
+ assert_eq!(taffy.layout(flow_root).unwrap().size.height, 30.0);
+}
+
+#[test]
+fn flow_root_sibling_avoids_float() {
+ let mut taffy = new_test_tree();
+ let float = taffy
+ .new_leaf(Style {
+ display: Display::Block,
+ float: Float::Left,
+ size: Size { width: length(30.0), height: length(20.0) },
+ ..Default::default()
+ })
+ .unwrap();
+ let flow_child =
+ taffy.new_leaf(Style { size: Size { width: auto(), height: length(10.0) }, ..Default::default() }).unwrap();
+ let flow_root = taffy
+ .new_with_children(
+ Style { display: Display::FlowRoot, size: Size { width: auto(), height: auto() }, ..Default::default() },
+ &[flow_child],
+ )
+ .unwrap();
+ let parent = taffy
+ .new_with_children(
+ Style {
+ display: Display::Block,
+ size: Size { width: length(100.0), height: auto() },
+ ..Default::default()
+ },
+ &[float, flow_root],
+ )
+ .unwrap();
+ taffy.compute_layout(parent, Size::MAX_CONTENT).unwrap();
+
+ assert_eq!(taffy.layout(flow_root).unwrap().location, Point { x: 30.0, y: 0.0 });
+ assert_eq!(taffy.layout(flow_root).unwrap().size.width, 70.0);
+}