blitz-dom: `Node::hit` ignores overflow clips and clip-path
Generated from repros/blitz-dom-hit-ignores-clips/README.md when the site was built at 7aa23e2.
What niso does
Section titled “What niso does”crates/niso-core/src/input.rs: collect_hits walks the boxes the way Node::hit_inner does, but skips a box
whose clip-path or CSS clip leaves the point out, and skips what a box holds when the point lies outside that
box’s padding box on an axis whose overflow is not visible. Dom::hit (elementFromPoint, pointer dispatch) and
Dom::hits (elementsFromPoint) both use that walk instead of BaseDocument::hit.
Expected vs actual
Section titled “Expected vs actual”Node::hit_inner (packages/blitz-dom/src/node/node.rs:1428) tests a box against its border box and its
scrollable overflow, then recurses into its children with no clip. Paint clips the children of a box whose
overflow is not visible to its padding box (should_clip_node in blitz-paint/src/render.rs), and clips a
box with clip-path to its shape (clip_path_shape), so the hit test finds boxes that are not drawn there.
Viewport 800x600. A 100x50 overflow: hidden box holds a 200px tall child, and a 100x100 box with
clip-path: circle(20px) sits at y = 150:
(10, 100) below the overflow: hidden box: expected not #inside, actual #inside(5, 155) in the circle's corner: expected not #circle, actual #circleCARGO_TARGET_DIR=~/.capy/work/repro-target cargo runExit status 1 while the bug reproduces, 0 once fixed. On Ubuntu, blitz needs sudo apt-get install -y libfontconfig-dev pkg-config.
Upstream main
Section titled “Upstream main”Same code. Blitz main was at 808ded9348289cac0a3b4940e69da21d5b918443 when checked (2026-11-09): hit_inner still
tests only the border box, the content rect and the scrollable overflow, with no clip.
Existing issue or PR
Section titled “Existing issue or PR”None found in a search of DioxusLabs/blitz issues and PRs for “hit test clip”, “overflow hidden click” and “clip-path hit”.
Issue text
Section titled “Issue text”Title: Node::hit finds boxes hidden by overflow clips and clip-path
Body:
BaseDocument::hit returns boxes that paint clips away: content overflowing an overflow: hidden (or
clip, auto, scroll) box outside its padding box, and the parts of a box outside its clip-path.
Clicks there land on content the user cannot see.
use blitz_dom::DocumentConfig;use blitz_html::HtmlDocument;use blitz_traits::shell::{ColorScheme, Viewport};
const HTML: &str = r#"<!DOCTYPE html><html><body style="margin:0"><div id="overflow" style="overflow:hidden;width:100px;height:50px"><div id="inside" style="height:200px"></div></div><div id="circle" style="width:100px;height:100px;margin-top:100px;clip-path:circle(20px)"></div></body></html>"#;
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); let mut failed = false; for (what, x, y, wrong) in [("below the overflow: hidden box", 10.0, 100.0, "inside"), ("in the circle's corner", 5.0, 155.0, "circle")] { let hit = doc.hit(x, y).map(|h| h.node_id); let id = hit.and_then(|id| doc.get_node(id)).and_then(|n| n.attr(blitz_dom::local_name!("id"))).unwrap_or("").to_string(); println!("({x}, {y}) {what}: expected not #{wrong}, actual #{id}"); failed |= id == wrong; } if failed { std::process::exit(1); }}Tested at be60597f67b3cece0456d26e8d7ff5a88600bbc5. A fix: in hit_inner, return early when the point is outside
the box’s clip-path shape (the one clip_path_shape builds for paint) or its CSS clip rect, and skip the
children and inline content when the point is outside the padding box on an axis whose overflow is not visible.