From 5214d7a1e394f0f4dec27b0dbe64787c84cf64a5 Mon Sep 17 00:00:00 2001 From: Pierre Le Fevre Date: Sun, 22 Mar 2026 08:56:15 +0100 Subject: [PATCH] Fix normalize_children to wrap inline content alongside floats When a container has only float children and bare inline content (no in-flow block siblings), normalize_children returned early without wrapping the inline content in anonymous blocks. This caused the text to be silently dropped during layout_block_children since compute_layout is a no-op for TextRun/Inline boxes. Include floated children in the has_block check so that inline content gets properly wrapped in anonymous blocks and laid out through the inline formatting context. Co-Authored-By: Claude Opus 4.6 (1M context) --- crates/layout/src/lib.rs | 46 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/crates/layout/src/lib.rs b/crates/layout/src/lib.rs index d18842f..7e0b254 100644 --- a/crates/layout/src/lib.rs +++ b/crates/layout/src/lib.rs @@ -462,8 +462,13 @@ fn normalize_children(children: Vec, parent_style: &ComputedStyle) -> return children; } - // Only consider in-flow children for block/inline normalization. - let has_block = children.iter().any(|c| is_in_flow(c) && is_block_level(c)); + // Consider in-flow block children and floated children as "block-level" + // for normalization purposes. When floats are present alongside inline + // content, the inline content must be wrapped in anonymous blocks so that + // `layout_block_children` can lay it out via its inline formatting context. + let has_block = children + .iter() + .any(|c| (is_in_flow(c) && is_block_level(c)) || is_floated(c)); if !has_block { return children; } @@ -5429,4 +5434,41 @@ body { margin: 0; } ); } } + + #[test] + fn bare_text_alongside_float_is_laid_out() { + // When a container has only float children + bare text (no block + // siblings), the text should still be wrapped in an anonymous block + // and laid out correctly. + let mut doc = Document::new(); + let root = doc.root(); + let html = doc.create_element("html"); + let body = doc.create_element("body"); + let container = doc.create_element("div"); + let float_elem = doc.create_element("div"); + let text = doc.create_text("Hello world"); + doc.append_child(root, html); + doc.append_child(html, body); + doc.append_child(body, container); + doc.append_child(container, float_elem); + doc.append_child(container, text); + doc.set_attribute(container, "style", "width: 400px;"); + doc.set_attribute( + float_elem, + "style", + "float: left; width: 100px; height: 50px;", + ); + + let tree = layout_doc(&doc); + let body_box = &tree.root.children[0]; + let container_box = &body_box.children[0]; + + // The text should be wrapped in an anonymous block and produce text lines. + let has_text = container_box.children.iter().any(|c| !c.lines.is_empty()); + assert!( + has_text, + "bare text alongside a float should be laid out (found {} children, none with text lines)", + container_box.children.len(), + ); + } } -- 2.51.2