render: ignore non-items in flex layout
This commit is contained in:
1 parent
f8aac61c0b
commit
64b628404b
1 file changed
+19
-8
@@ -1953,18 +1953,29 @@ fn build(
|
|||||||
has_inline_content(tree, id, styles) || style.before_content.is_some() || style.after_content.is_some();
|
has_inline_content(tree, id, styles) || style.before_content.is_some() || style.after_content.is_some();
|
||||||
|
|
||||||
let mut dom_children = tree.children(id);
|
let mut dom_children = tree.children(id);
|
||||||
// In a grid formatting context, whitespace-only text between items does not
|
// In flex and grid formatting contexts, collapsible whitespace-only text
|
||||||
// generate an anonymous grid item (CSS Grid). taffy 0.12 places each stray
|
// between items does not generate an anonymous item. Taffy places each
|
||||||
// whitespace text node in its own cell, which offsets every real item, so a
|
// stray whitespace leaf in the item sequence, shifting every real child.
|
||||||
// Tailwind `grid-cols-3` block with newlines between its children lays out
|
// This is especially visible in pretty-printed HTML: indentation before a
|
||||||
// diagonally instead of in one row (this collapsed the whole modern
|
// flex child becomes several pixels of unexplained leading space.
|
||||||
// framework cluster after the taffy upgrade). Drop them before building.
|
//
|
||||||
if style.display == crate::Display::Grid {
|
// Flatten display:contents first because its children participate as direct
|
||||||
|
// flex/grid items. Otherwise formatting whitespace inside the transparent
|
||||||
|
// wrapper would survive this filter and become an item in `build_any`.
|
||||||
|
if matches!(style.display, crate::Display::Flex | crate::Display::Grid) {
|
||||||
|
let mut flat = Vec::new();
|
||||||
|
flatten_contents_children(tree, &dom_children, styles, &mut flat);
|
||||||
|
dom_children = flat;
|
||||||
dom_children.retain(|&cid| {
|
dom_children.retain(|&cid| {
|
||||||
tree.get_node(cid).map_or(false, |n| n.is_element()) || !tree.text_content(cid).trim().is_empty()
|
tree.get_node(cid).map_or(false, |n| n.is_element()) || !tree.text_content(cid).trim().is_empty()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let has_float_child = dom_children.iter().any(|&cid| styles.get(&cid).map(|s| s.float.is_some()).unwrap_or(false));
|
// `float` has no effect on a flex or grid item. Legacy stylesheets often
|
||||||
|
// leave floats on children after a newer rule turns their parent into a
|
||||||
|
// flex container; routing those children through the block float-zone
|
||||||
|
// approximation corrupts flex sizing and percentage-margin placement.
|
||||||
|
let has_float_child = style.display == crate::Display::Block
|
||||||
|
&& dom_children.iter().any(|&cid| styles.get(&cid).map(|s| s.float.is_some()).unwrap_or(false));
|
||||||
|
|
||||||
// A block with mixed inline + block children keeps real block layout:
|
// A block with mixed inline + block children keeps real block layout:
|
||||||
// block-level children become direct block children (full available
|
// block-level children become direct block children (full available
|
||||||
|
|||||||
Reference in new issue
Block a user