Focus policy
The focusPolicy style decides whether a node stops the pointer from
reaching what lies beneath it: other UI nodes, and the 3D scene behind the
UI. "block" stops it; "pass" lets it through. Despite the name (it comes
from Bevy), it has nothing to do with keyboard focus.
Usage
A modal backdrop that keeps hover, clicks and scene picking away from everything behind it:
<node
style={{
positionType: "absolute",
width: "100%",
height: "100%",
backgroundColor: "rgba(0, 0, 0, 0.5)",
focusPolicy: "block",
}}
>
<Dialog />
</node>Values
| Value | Effect | Default for |
|---|---|---|
"pass" |
Nodes and the scene beneath still see the pointer | Every element but <button> |
"block" |
Nothing beneath the node sees the pointer | <button> |
An explicit value overrides the element's default, on a <button> too. An
unknown value reports a focusPolicy warning and acts as "pass".
What blocking stops
Under the pointer, nodes are visited from the topmost down (see Z-index) until the first blocking node, which is included. Everything beneath it is out of reach:
- Hover and press. Only the visited nodes are hovered or pressed, which
drives
hoverStyle,pressStyle,onPointerEnterandonPointerLeave. That includes the blocking node's own ancestors, which are beneath it: a<button>inside a hover-styled card un-hovers the card while the pointer is on the button. Give the buttonfocusPolicy: "pass"if the card should stay hovered; the button still gets its own clicks. - Clicks. One click fires one handler, chosen from the topmost visited node that has a click handler on itself or an ancestor (see Mouse events). A click on a blocking overlay without a handler can only reach a handler on the overlay's ancestors, never the nodes beneath it.
- 3D scene picking. Bevy picking on meshes and sprites behind the UI
(for example with
MeshPickingPlugin) only sees the pointer through passing nodes. A blocking node hides the scene behind it.
With "pass" everywhere, every node under the pointer is hovered, and a
click goes to the topmost handler among them.
Input your own systems read
focusPolicy affects picking and hover only. Systems that read the mouse
directly, such as a camera controller, should check the PointerCapture
resource instead, which reports when the UI owns the pointer. It reports
the pointer as over the UI while it hovers an interactive node (one with a
click or pointer handler, a hoverStyle or pressStyle, or a <button>),
whatever that node's focus policy. A plain panel with no handlers doesn't
capture the pointer, even with "block". See
Mouse events.
Behavior
- Transparency doesn't matter: a node at
opacity: 0or with no background still blocks or passes by its policy.display: "none"removes it from hit testing. - A
<root>never takes part in hit testing itself; its children do, by their own policies. - In a
<surface>, the policy applies the same way to the in-world pointer.
See focusPolicy in the
style reference.
bevy-react