Every click, tap, or hover on a website starts with the browser figuring out what element the user actually touched. That process — officially called hit-testing — decides which element becomes the target of a pointer event. The CSS property pointer-events is how you control that behavior.

Think of it as a gatekeeper. When you set pointer-events: none on an element, the browser skips that element entirely and looks at whatever is underneath. The element still exists visually, but it becomes invisible to clicks, taps, and hovers.

How the browser picks the target

Normally, the browser selects the topmost element under the pointer. If that element has pointer-events: none, the browser ignores it and moves down to the next layer. This is why overlays and modals often use this technique — so the user can still interact with background elements behind the overlay.

Values you'll actually use

For most HTML work, you only need two values:

  • auto (default) — normal behavior, element receives pointer events
  • none — element is skipped during hit-testing

SVG elements offer additional fine-grained control. Nine extra values let you specify whether a graphic responds to pointer events based on its fill, stroke, visibility, or bounding box. For example, visibleFill makes an SVG element clickable only when the pointer is over its painted fill area, while bounding-box makes the entire rectangle around the shape clickable regardless of where the actual graphic is drawn.

Children can opt back in

Here is a critical detail: pointer-events is inherited. If you set it to none on a parent, all children inherit that value by default. However, any child can override it:

.parent { pointer-events: none; }
.child { pointer-events: auto; }

This pattern is especially useful for modals. You create a full-page overlay container that blocks clicks by default, then re-enable pointer events only on the modal content itself. The result: users can interact with the modal and also click buttons visible behind the overlay.

Event propagation is preserved

This property only affects target selection, not event flow. If a child with pointer-events: auto is clicked inside a parent with pointer-events: none, the event.target will be the child. But the event still bubbles up to the parent, so any event listeners attached to the parent will fire as usual.

For example, a click listener on the parent still runs. The only difference is that event.target reports the child, not the parent. This behavior is the same for pointerenter and pointerleave events.

Practical use cases for Cyprus and EU businesses

When building multilingual sites (EN/RU/EL) or complex web apps with CRM or ERP dashboards, you'll encounter these scenarios:

  • Overlays and pop-ups: Keep the background interactive while showing a modal — avoid frustrating users on mobile
  • Custom menus and dropdowns: Prevent accidental clicks on hidden submenu items when hovering
  • Loading states: Temporarily block interactions on a section while data loads, without removing elements from the DOM
  • SVG maps or diagrams: In an interactive infographic, make only specific regions clickable using SVG-specific values like visibleFill
  • GDPR compliance: Redirect all clicks to a consent banner without rewriting your entire click-handling logic

One common pitfall: developers try to use pointer-events to disable form buttons. This works visually but remember — the property only prevents pointer events. Keyboard users can still activate the button. For true disabled state, use the disabled attribute instead.

Implementation is straightforward. No JavaScript libraries, no complex event delegation. Just a single CSS declaration that changes how the browser resolves which element is under the user's finger or cursor. The result is cleaner code and a more predictable interaction model for your website or web app.