Skip to content

blitz-dom: table rows and row groups have no box

Generated from repros/blitz-dom-table-row-box/README.md when the site was built at 7aa23e2.

Found by Acid1/Acid2 layout comparisons. crates/niso-core/src/geometry.rs: Dom::table_part_rect gives Element.getBoundingClientRect() a row’s or row group’s box from the table’s grid, the table’s columns across the grid rows it holds, so it matches Chrome wherever blitz sizes the rows as Chrome does. The render stream still has no native view for rows and row groups (crates/niso-core/src/render.rs places views at blitz’s layout boxes), so their backgrounds and borders do not paint.

blitz-dom layout/table.rs. The table is flattened into a grid of cells: the row-group and row arms of collect_table_cells (table.rs:555-587, table.rs:588-622) only recurse into their children and record row heights; the <tbody>/<tr> nodes never become layout children (their layout_parent is None), so their layout is the default 0x0 at 0,0. Rows and row groups are boxes in CSS 2.1 §17.5 (they have dimensions, take backgrounds, and are hit-testable and measurable).

<table><tbody><tr><td style="height:20px">x</td></tr></tbody></table> (border-spacing 0, td padding 0):

<tbody>: expected (0, 0, 6.34375, 20), actual (0, 0, 0, 0)
<tr>: expected (0, 0, 6.34375, 20), actual (0, 0, 0, 0)

(6.34375 is the table’s width with the system sans-serif.) Chrome 156: tbody and tr = 0, 0, table width, 20. A display: table-row div behaves the same (0x0).

Terminal window
CARGO_TARGET_DIR=~/.capy/work/repro-target cargo run

Exit status 1 while the bug reproduces, 0 once fixed. Needs libfontconfig-dev pkg-config on Ubuntu. Built with blitz-dom features system-fonts, accessibility, floats (as niso), viewport 800x600 at scale 1.

Reproduces. Blitz main was still at be60597f67b3cece0456d26e8d7ff5a88600bbc5 (niso’s pin) when tested on 2026-11-08, so the pinned result is the main result.

Tested against open PR https://github.com/DioxusLabs/blitz/pull/1370 (“Use Taffy table layout for CSS tables”, head 0c20c4e7ffadf356bd4ae04bd90e3cf3342da8b2, pins Taffy b2bd579 from DioxusLabs/taffy#1380) with path dependencies on a local checkout: fixed there (exit 0).

No issue found (searched blitz issues/PRs for table, row, tbody). https://github.com/DioxusLabs/blitz/pull/1370 (open) fixes it by giving row groups and rows real boxes. #1002 (merged) paints row-group backgrounds from the cells, without giving the rows boxes.

Title: Table rows and row groups have no layout box (get_client_bounding_rect is 0×0)

Body:

Tables are laid out as a grid of their cells, so <tr>, <tbody>/<thead>/<tfoot> and display: table-row / table-row-group elements never get a layout box: final_layout() and get_client_bounding_rect are 0×0 at 0,0. Browsers give them the box spanning their cells (CSS 2.1 §17.5), which embedders need for getBoundingClientRect, hit testing and row backgrounds.

use blitz_dom::DocumentConfig;
use blitz_html::HtmlDocument;
use blitz_traits::shell::{ColorScheme, Viewport};
const HTML: &str = r#"<body style="margin:0;font:12px/12px sans-serif">
<table style="border-spacing:0"><tbody id="tbody"><tr id="tr"><td style="padding:0;height:20px">x</td></tr></tbody></table></body>"#;
fn main() {
let config = DocumentConfig { viewport: Some(Viewport::new(800, 600, 1.0, ColorScheme::Light)), ..Default::default() };
let mut doc = HtmlDocument::from_html(HTML, config);
doc.resolve(0.0);
for id in ["tbody", "tr"] {
let r = doc.get_client_bounding_rect(doc.get_element_by_id(id).unwrap()).unwrap();
println!("{id}: {} {} {} {}", r.x, r.y, r.width, r.height); // Chrome: 0 0 <table width> 20; blitz: 0 0 0 0
}
}

Tested at be60597; fixed by #1370 (0c20c4e).