Why Background Elements Receive Clicks in Pixi.js
In Pixi.js, developers often encounter scenarios where an interactive element positioned behind another object still registers click or pointer events. This behavior typically stems from how Pixi.js handles hit-testing, input propagation, and the scene graph hierarchy. Understanding how the interaction system processes pointer events is key to ensuring that foreground elements properly block interactions from reaching background layers.
1. The Foreground Element is Non-Interactive
The most common cause of this issue is that the overlapping foreground element is not configured to receive pointer events. In Pixi.js, elements do not block pointer events by default. If a foreground container or sprite is purely visual, Pixi.js passes the click event straight through it to the first interactive element it finds underneath.
How to fix: You must explicitly enable interactivity
on the foreground element so it intercepts the hit-test. *
Pixi.js v7+: Set
foreground.eventMode = 'static' or 'dynamic'.
* Pixi.js v6 and below: Set
foreground.interactive = true.
2. Missing or Empty Hit Area on the Foreground Element
Even if a foreground element is marked as interactive, it can only
block clicks if the Pixi.js hit-testing algorithm detects a collision
with it. If the foreground element has no visible texture, has a scale
of zero, or is an empty Container with no dimensions, the
hit-test will fail, and the click will pass through to the
background.
How to fix: Define an explicit hit area for the foreground element to ensure it occupies physical space in the interaction system:
foregroundElement.hitArea = new PIXI.Rectangle(0, 0, width, height);3. Incorrect Event Mode Configuration
Pixi.js v7 introduced eventMode to replace the boolean
interactive property. If the foreground element is set to
an incorrect event mode, it may not block events: * none:
Ignores all events (allows pass-through). * passive:
Receives events but does not prevent them from propagating or
hit-testing other elements. * auto: Default behavior; acts
as none unless interactive children are present. *
static or dynamic: Actively intercepts and
blocks events from passing through to underlying objects.
Ensure your foreground element is set to 'static' or
'dynamic'.
4. Lack of Event Propagation Control
If both the foreground and background elements are interactive, the click event might trigger on both if the interaction system propagates the event up the scene graph. Pixi.js resolves hit-testing from the top-most rendered element down. However, if your scene graph structure places the background element as a parent of the foreground element, the click event will bubble up to the parent.
How to fix: To stop an event from bubbling up to
parent containers, use stopPropagation() inside the event
handler of the foreground element:
foregroundElement.on('pointerdown', (event) => {
event.stopPropagation();
// Handle foreground click
});5. Render Order vs. Scene Graph Order
Pixi.js performs hit-testing based on the tree structure of your
scene graph, traversing it in reverse order (from last-rendered child to
first-rendered child). If the background element is actually placed
after the foreground element in the container’s child array, Pixi.js
will evaluate the background element first during a click event, even if
visual sorting (such as custom zIndex properties) makes it
look like it is behind.
How to fix: Ensure that your visual layer order
matches your logical child order, or verify that
sortableChildren is enabled on the parent container if you
are relying on zIndex to position elements:
parentContainer.sortableChildren = true;
foregroundElement.zIndex = 2;
backgroundElement.zIndex = 1;