From f62ce2604ede65a9400441c3e959d2855a7d5ad7 Mon Sep 17 00:00:00 2001 From: SGavrl <277843151+SGavrl@users.noreply.github.com> Date: Fri, 31 Jul 2026 04:04:44 +0000 Subject: [PATCH] Contain definite floats through clearfix bands --- crates/obscura-render/src/dom.rs | 22 +++++++++++--- crates/obscura-render/tests/layout_test.rs | 34 ++++++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/crates/obscura-render/src/dom.rs b/crates/obscura-render/src/dom.rs index b01d0bb..c7a13fe 100644 --- a/crates/obscura-render/src/dom.rs +++ b/crates/obscura-render/src/dom.rs @@ -7952,7 +7952,13 @@ fn build_children_with_float_zone( crate::Dimension::Px(_) | crate::Dimension::Percent(_) ) && parent.size_expressions[1].is_none() }); - if parent_has_definite_height { + let parent_has_clearfix = styles.get(&parent_id).is_some_and(|parent| { + parent.after_pseudo.as_deref().is_some_and(|after| { + matches!(after.clear, Some(crate::Clear::Left | crate::Clear::Both)) + && has_in_flow_generated_pseudo(Some(after)) + }) + }); + if parent_has_definite_height || parent_has_clearfix { let fills_axis = |value: f32| (value - 1.0).abs() < 0.001; let substantive: Vec = dom_children .iter() @@ -7979,10 +7985,14 @@ fn build_children_with_float_zone( matches!(style.height, crate::Dimension::Percent(value) if fills_axis(value)) && style.size_expressions[1].is_none() }); + let float_has_definite_height = float_style.is_some_and(|style| { + matches!(style.height, crate::Dimension::Px(_)) && style.size_expressions[1].is_none() + }) || float_fills_height; let sole_full_width_float = substantive.len() == 1 && float_percent_width.is_some_and(fills_axis) - && float_fills_height; - let split_band_flow = if substantive.len() == 2 + && float_has_definite_height; + let split_band_flow = if parent_has_definite_height + && substantive.len() == 2 && substantive[0] == float_dom && float_style.and_then(|style| style.float) == Some(crate::Float::Left) && float_fills_height @@ -8053,7 +8063,11 @@ fn build_children_with_float_zone( align_items: Some(taffy::AlignItems::FLEX_START), size: taffy::Size { width: taffy::Dimension::percent(1.0), - height: taffy::Dimension::percent(1.0), + height: if parent_has_definite_height { + taffy::Dimension::percent(1.0) + } else { + taffy::Dimension::auto() + }, }, ..Default::default() }; diff --git a/crates/obscura-render/tests/layout_test.rs b/crates/obscura-render/tests/layout_test.rs index 064d17e..3bbd004 100644 --- a/crates/obscura-render/tests/layout_test.rs +++ b/crates/obscura-render/tests/layout_test.rs @@ -944,6 +944,40 @@ fn full_width_percentage_float_uses_definite_containing_block() { ); } +#[test] +fn clearfix_contains_a_full_width_definite_height_float() { + let tree = parse_html( + r#" + +
+ "#, + ); + let layout = layout_dom(&tree, (800.0, 700.0)); + let rect = |id| layout.rects[&tree.get_element_by_id(id).unwrap()]; + let host = rect("host"); + let float = rect("float"); + assert!( + (host.x - 0.0).abs() < 0.01 + && (host.y - 0.0).abs() < 0.01 + && (host.width - 800.0).abs() < 0.01 + && (host.height - 600.0).abs() < 0.01, + "host: {host:?}" + ); + assert!( + (float.x - 0.0).abs() < 0.01 + && (float.y - 0.0).abs() < 0.01 + && (float.width - 800.0).abs() < 0.01 + && (float.height - 600.0).abs() < 0.01, + "float: {float:?}" + ); +} + #[test] fn percentage_float_and_inline_sibling_share_definite_height_band() { let tree = parse_html(