Engineering Journal
Schema Editor
Schema Editor

SVG fill:none Shapes Have No Clickable Interior

2026-07-17

TLDR

SVG elements configured with fill="none" ignore pointer clicks inside their bounding interior because the default browser hit-testing mode is pointer-events: visiblePainted. Under visiblePainted, pointer events fire only on visually painted strokes (e.g., a 2px stroke outline). Applying pointer-events: all to user-drawn closed shapes (rect, ellipse, polygon) makes their interior clickable, while scoping open paths (wire, path) to stroke-only hitboxes to prevent phantom hit regions.
SVG Geometry CategoryDefault Hit BehaviorCSS OptimizationTarget Hit Area
Closed Shapes (rect, circle)Stroke outline onlypointer-events: allFull interior area + stroke
Open Paths (wire, path)Stroke outline onlyInvisible fat stroke cloneStroke target + fat hit buffer

Problem statement: the hollow element hit defect

In schema and diagram editors, shapes (rectangles, containers, components) are styled with outlined borders and transparent interiors: fill="none", stroke="#333".

Users clicking inside an unfilled rectangle to select or drag it find that the click passes through to elements underneath.

To select the shape, users are forced to click directly on the 2px stroke border, a difficult target on touch screens and trackpads.


Technical failure mode: visiblePainted hit specifications

The W3C SVG specification defaults pointer testing to pointer-events: visiblePainted.

For an SVG shape with fill="none", no pixels are painted inside its interior bounding area. The browser evaluates the interior as pointer-transparent.

Applying pointer-events: all across all SVG elements blindly breaks open paths: for an L-shaped wire, pointer-events: all treats the invisible triangle connecting its endpoints as a filled interior, causing wires to intercept clicks meant for adjacent components.


The fix & architecture: topology-aware CSS hit rules

Step 1: CSS scoping for closed shapes

Apply pointer-events: all strictly to closed geometric elements (rect, circle, ellipse, polygon):
/ Enable interior hit-testing for user-drawn closed canvas shapes /
#canvas rect[id^="el_"],
#canvas circle[id^="el_"],
#canvas ellipse[id^="el_"],
#canvas polygon[id^="el_"] {
  pointer-events: all;
}

This makes transparent interiors responsive to mouse and touch events without adding extra DOM nodes.

Step 2: fat hitbox clones for open paths

For open wires and polylines, retain visiblePainted and generate a secondary, transparent stroke clone with a wider stroke width ($12\text{px}$) to expand the hit target without creating phantom interior hit regions:
<!-- Open Wire Geometry: Thin visible wire + Fat transparent hit stroke -->
<g class="wire-group">
  <!-- Invisible fat hit stroke -->
  <path d="M 10 10 L 100 10" stroke="transparent" stroke-width="12" pointer-events="stroke" />
  <!-- Visible thin wire -->
  <path d="M 10 10 L 100 10" stroke="#00e5ff" stroke-width="2" pointer-events="none" />
</g>
Rule of thumb: Apply pointer-events: all to transparent closed shapes (rect, circle) for interior clickability. Use widened transparent stroke clones for open wire paths.
Read this post in the full Engineering Journal →