DocsWhat an action waits for

What an action waits for

The checks every action passes before real input is sent, and again when the press arrives.

  1. the map is scrolled into the browser viewport if it is not (a map further down a page cannot be reached by any pointer)
  2. the query resolves to exactly one feature, and the style actually paints it (not opacity 0 / transparent)
  3. the map is not moving, the target pixel is stable across two frames, and the map's own place on the page holds still (a CSS transition or animation of its container, or a collapsing sidebar, makes the action wait; location actions and drags check this too)
  4. the pixel is on the feature — for polygons an interior point far from the edge, never the centroid
  5. the feature is the topmost visible hit at that pixel (its own label on top does not count as an occluder; neither does anything the style paints invisibly, e.g. a transparent hit area)
  6. no DOM element (popup, control, overlay) covers the pixel
  7. a layer the hit test cannot see (raster, image, video, canvas, heatmap, hillshade, color-relief, background, and custom layers such as deck.gl's) drawn above the feature at that pixel: the feature's own layer is probed there, and if hiding it changes no pixel the point is covered and the next one is tried (a translucent overlay, or a transparent gap in an opaque one, lets the action through; so does a heatmap that draws nothing there, although MapLibre 5 and later hit-test it over its whole radius; a target that itself draws nothing at that pixel, such as a ring marker's transparent middle or the inside of a polygon drawn only by its outline, reads as covered even under a translucent overlay: Limits). Each action probes anew. Maps without such a layer above their features pay nothing
  8. at the instant the real pointerdown arrives, the hit test is re-run; if the feature the query resolved to is no longer there (a look-alike that slid under the pointer does not count), is painted invisibly since the aim, or a layer of item 6 appeared over it since the aim, the click — or the tap, touch events included — is swallowed and the action retries

Works unchanged on rotated, pitched, globe and terrain maps, and on a map inside a container scaled with CSS transform: scale(). A location on the far side of the globe, behind the camera or hidden behind a mountain is an error, never a click on whatever is drawn at that pixel, and a feature query at such a location matches nothing. Features need no ids: identity is id + properties, and id-less look-alikes are told apart by where they are drawn.

Escape hatches: { force: true }, { ignoreLayers: [...] } (per action or per map; never the target's own layer), { autoPan: true }, { timeout }, and { moving: 'allow' } for a target that never stops moving (click, tap, hover: the pointer leads it; a press that arrives late, or when the query matches more than one feature, is swallowed before the app sees it — it can time out, it never presses another feature (for dblclick, its first press); a press that was let through is checked again at the click event, where MapLibre decides what was clicked: a target that slipped off in between is a failure after input, never a reported success; dragTo, dragBy, lngLat and the location actions (clickAt, hoverAt, tapAt…) have no such check and refuse the option). The reasoning and the measurements: DESIGN — Actionability.

Why each check exists, and what happens when the press arrives, is explained in How an action is verified.