CSS pointer-events Property
The pointer-events property controls how a graphical element responds to mouse, touch, or stylus interactions.
| auto | The element behaves normally and responds to all pointer events as expected. |
| none | The element is never the target of pointer events, letting them pass through to elements underneath. |
| visiblePainted | SVG only: events fire if the pointer is over the painted area of a visible element. |
| visibleFill | SVG only: events fire if the pointer is over the fill of a visible element. |
| visibleStroke | SVG only: events fire if the pointer is over the stroke of a visible element. |
| visible | SVG only: events fire if the pointer is over any part of a visible element. |
| painted | SVG only: events fire if the pointer is over the painted area regardless of visibility. |
| fill | SVG only: events fire if the pointer is over the fill regardless of visibility. |
| stroke | SVG only: events fire if the pointer is over the stroke regardless of visibility. |
| all | SVG only: events fire if the pointer is over any part of the element regardless of visibility. |
| inherit | The element adopts the pointer-events value defined by its parent element. |
Code Examples
A basic example showing a red overlay that is visually on top of a button but allows clicks to pass through to that button.
<div style="position: relative; width: 300px; height: 100px; border: 1px solid #000000;">
<button onclick="alert('Button Clicked!')" style="margin: 20px;">Target Button</button>
<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(255, 0, 0, 0.4); pointer-events: none; color: #ffffff; display: flex; align-items: center; justify-content: center;">
I am a ghost overlay (Click through me)
</div>
</div>An advanced scenario where a full-screen UI layer allows clicking the background while its own buttons are active, and JavaScript is used to prevent double-submissions by toggling interaction.
<div id="ui-layer" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none;">
<button id="save-btn" style="pointer-events: auto; background: #007bff; color: #ffffff; padding: 10px;" onclick="saveData()">
Save Progress
</button>
</div>
<script>
function saveData() {
const btn = document.getElementById("save-btn");
btn.innerText = "Saving...";
btn.style.pointerEvents = "none";
btn.style.opacity = "0.5";
setTimeout(() => {
btn.innerText = "Save Progress";
btn.style.pointerEvents = "auto";
btn.style.opacity = "1.0";
btn.style.backgroundColor = "#28a745";
alert("Data saved to database");
}, 2000);
}
</script>Pro Tip
You can create a click-through container with interactive children. Set the parent container to pointer-events: none so clicks pass through the empty space, then set the specific child buttons back to pointer-events: auto so they remain clickable. This is perfect for complex HUDs or gaming interfaces where you want to click the world behind the UI through the gaps.
Deep Dive
Think of pointer-events: none like turning an element into a ghost. It stays visually present on the screen, but the mouse cursor or a user's finger passes right through it, hitting whatever is sitting directly behind it in the stack. By default, most elements are set to auto, meaning they stop the cursor and trigger hover or click states. In the SVG world, this property gets much more granular, allowing you to target just the stroke or just the fill of a shape. For standard HTML, you will mostly stick to auto or none. It is a powerful tool for layout layering where a decorative overlay should not block the functional buttons underneath.
Best Practices
Apply pointer-events: none to decorative icons, floating labels, or glass-morphism overlays that might sit on top of links or buttons. This ensures your user interface remains functional even if your design calls for overlapping elements. If you need to disable a whole section of a page during a process, applying pointer-events: none to a parent container is an efficient way to stop all child interactions at once.
Common Pitfalls
One common mistake is thinking pointer-events: none makes an element invisible; it does not. It only affects interaction. Another trap is accessibility; keyboard users can often still tab to and interact with elements that have pointer-events: none set, because it specifically targets pointer devices, not keyboard focus. Also, remember that if you set this on a parent, all children inherit it unless you explicitly set the children back to auto.
Accessibility
Do not rely on pointer-events: none to secure an interface. A user can still use the Tab key to reach links or buttons hidden behind a ghost element. If you want to truly disable an element for all users, use the HTML disabled attribute or aria-disabled="true" to ensure screen readers and keyboard users understand the element is currently off-limits. This property only silences the mouse and touch sensors.
Dev Data Table: pointer-events property
| default | auto |
| animatable | no |
| inherited | yes |
| experimental | no |
| year_intro | 2004 |
| year_standard | 2011 |
| js_syntax_1 | element.style.pointerEvents = "none"; |
| js_syntax_2 | element.style.setProperty("pointer-events", "none"); |
| js_note | Useful for toggling interactivity on overlays or loading states through logic. |
| browsers | { "Chrome": 1, "Edge": 12, "Firefox": 3.6, "Safari": 4, "Opera": 15, "Chrome Android": 18, "Safari on iOS": 3.2, "Samsung Internet": 1, "Opera Mobile": 12 } |